544
Wine acronym (lemmy.ca)
submitted 3 months ago* (last edited 3 months ago) by ColdWater@lemmy.ca to c/linuxmemes@lemmy.world
you are viewing a single comment's thread
view the rest of the comments
[-] SexualPolytope@lemmy.sdf.org 5 points 3 months ago* (last edited 3 months ago)
wine = iterate (++" Is Not an Emulator") "WINE"
[-] ColdWater@lemmy.ca 5 points 3 months ago
Internal errors - invalid parameters received
[-] SexualPolytope@lemmy.sdf.org 4 points 3 months ago* (last edited 3 months ago)

Sorry, I should've specified, it's in Haskell. Idk where you tried running it.

[-] lennivelkant@discuss.tchncs.de 4 points 3 months ago

I've never worked with Haskell, but I've been meaning to expand my programming repertoire (particularly since I don't get to do much coding at work, let alone learn new languages) and this makes for a nice opportunity, so I wanna try to parse this / guess at the syntax.

I assume iterate function arg applies some function to arg repeatedly, presumably until some exit condition is met? Or does it simply create an infinite, lazily evaluated sequence?

( ) would be an inline function definition then, in this case returning the result of applying ++suffix to its argument (which other languages might phrase something like arg += suffix), thereby appending " Is Not an Emulator" to the function argument, which is initially "WINE".

So as a result, the code would produce an infinite recurring "WINE Is Not an Emulator Is Not an Emulator..." string. If evaluated eagerly, it would result in an OOM error (with tail recursion) or a stack overflow (without). If evaluated lazily, it would produce a lazy string, evaluated only as far as it is queried (by some equivalent of a head function reading the first X characters from it).

How far off am I? What pieces am I missing?

[-] SexualPolytope@lemmy.sdf.org 2 points 3 months ago* (last edited 3 months ago)

You're pretty much right on the money. In Haskell, a String is a type synonym for [Char], so we can use the list concatenation function ++ to join strings. ++ is an infix function i.e. [1,2,3] ++ [3,4,5] = [1,2,3,3,4,5] (which will be equivalent to doing (++) [1,2,3] [3,4,5] by virtue of how infix functions work in Haskell). When we do (++ "a"), we create a partially applied function. Now, we can supply another string to it and it will add "a" at the end of it.

iterate f x produces a lazily evaluated sequence [x, f x, f f x, ...]. So, to get the nth entry, we can do wine !! n where we use another infix function !!. With partial application, we can modify the definition of wine to create a function that takes an Int n and spits out the nth entry of it by doing

wine = (!!) $ iterate (++" Is Not an Emulator") "WINE"

We needed to wrap the !! inside parentheses because it's an infix function. $ just changes the order of application. (IIRC, it's the least significant function.) You can think that we're wrapping whatever's on the right of the $ by parentheses. Now we can do wine 2 instead of wine !! 2 to get "WINE Is Not an Emulator Is Not an Emulator".

I'm by no means a Haskell expert. (I'm not even a professional programmer lol.) So, if someone would like to add some more details, they're more than welcome.

Edit: A much more readable version might be

wine 0 = "WINE"
wine n = wine (n-1) ++ " Is Not an Emulator"
[-] lennivelkant@discuss.tchncs.de 2 points 3 months ago

[The list concatenation function] ++ is an infix function i.e. [1,2,3] ++ [3,4,5] = [1,2,3,3,4,5] (which will be equivalent to doing (++) [1,2,3] [3,4,5] by virtue of how infix functions work in Haskell).

I think that's the part I was most confused by. I'm coming mostly from Java and C, where ++ would be the unary operator to increment a number. I would have expected that symbol in a functional language context to be a shorthand for + 1. The idea of it being an infix function didn't occur to me.

Partial applications I remember from a class on Clojure I took years ago, but as far as I remember, the functions always had to come first in any given expression. Also, I believe partial fills the arguments from the left, so to add a suffix, I'd have to use a reversed str function. At that point, it would probably be more idiomatic to just create an inline function to suffix it. So if my distant recollection doesn't fail me, the Clojure equivalent of that partial function would be #(str % " Is Not an Emulator").

iterate works the same though, I think, so the whole expression would be (def wine (iterate #(str % " Is Not an Emulator") "WINE") )

This code was typed on a mobile phone in a quick break based off of years-old memories, so there might be errors, and given it was a single class without ever actually applying it to any problems, I have no real sense for how idiomatic it really is. I'll gladly take any corrections.

NGL though, that last, readable version is sexy as hell.

this post was submitted on 06 Aug 2024
544 points (97.6% liked)

linuxmemes

21211 readers
53 users here now

Hint: :q!


Sister communities:


Community rules (click to expand)

1. Follow the site-wide rules

2. Be civil
  • Understand the difference between a joke and an insult.
  • Do not harrass or attack members of the community for any reason.
  • Leave remarks of "peasantry" to the PCMR community. If you dislike an OS/service/application, attack the thing you dislike, not the individuals who use it. Some people may not have a choice.
  • Bigotry will not be tolerated.
  • These rules are somewhat loosened when the subject is a public figure. Still, do not attack their person or incite harrassment.
  • 3. Post Linux-related content
  • Including Unix and BSD.
  • Non-Linux content is acceptable as long as it makes a reference to Linux. For example, the poorly made mockery of sudo in Windows.
  • No porn. Even if you watch it on a Linux machine.
  • 4. No recent reposts
  • Everybody uses Arch btw, can't quit Vim, and wants to interject for a moment. You can stop now.

  • Please report posts and comments that break these rules!

    founded 1 year ago
    MODERATORS