|
in my hubris i keep writing shell scripts that inevitably grow to the point where I want to say "ok and now spawn a couple threads and then use channels to combine the results again" and then it turns out bash isn't go
|
# ? Feb 19, 2017 04:45 |
|
|
# ? May 22, 2024 08:51 |
|
jony neuemonic posted:perl's great at working with text and faking a portable unix. there's really no way it was going to be bad for scripting. its actually the worst at everything
|
# ? Feb 19, 2017 04:50 |
|
Shaggar posted:its actually the worst at everything -pe 's/worst/best/g'
|
# ? Feb 19, 2017 04:52 |
|
Shaggar posted:its actually the worst at everything hey man, I'm no fan of perl but at least it's not php
|
# ? Feb 19, 2017 05:16 |
|
Vanadium posted:in my hubris i keep writing shell scripts that inevitably grow to the point where I want to say "ok and now spawn a couple threads and then use channels to combine the results again" and then it turns out bash isn't go
|
# ? Feb 19, 2017 05:37 |
|
i went with haskell because new irl friend is also learning the language with me fyi bash scripting is utter garbage and only bitter old men use it bash is worse than javascript even
|
# ? Feb 19, 2017 05:47 |
|
this haskell error tripped me up for a while:code:
* Couldn't match type `Char' with `[Char]' Expected type: [[Char]] Actual type: String * In the second argument of `(++)', namely `str' In a stmt of a 'do' block: return "wtf: " ++ str In the expression: do { return "wtf: " ++ str } where did the [[Char]] come from? code:
you're not supposed to use 'return', this isn't C. this works: code:
|
# ? Feb 19, 2017 05:55 |
|
Ator posted:this haskell error tripped me up for a while: son i cant talk about this its got too may layers
|
# ? Feb 19, 2017 06:08 |
|
Ator posted:fyi bash scripting is utter garbage and only bitter old men use it
|
# ? Feb 19, 2017 06:35 |
|
in the context you're in, return is a function that takes some argument and produces a list containing that argument as its only element. So you basically did (return "wtf: ") ++ str, which is like doing ["wtf: "] ++ str basically, this is happening because haskell people generalize poo poo compulsively and most of it is silly and useless brap fucked around with this message at 07:48 on Feb 19, 2017 |
# ? Feb 19, 2017 06:58 |
|
that was a nice writeup rjmccall
|
# ? Feb 19, 2017 07:19 |
|
fleshweasel posted:in the context you're in, return is a function that takes some argument and produces a list containing that argument as its only element. So you basically did (return "wtf: ") ++ str, which is like doing ["wtf: "] ++ str even if you accept all the generalizations, there are like three major language design fuckups here the first is that the consensus call syntax in non-sexpr functional languages is terrible bullshit that trips newcomers up brutally all the time the second is that you can just put "do" there and it does nothing, completely accidentally, unless it fails to compile for reasons that once again make no sense to newcomers the third is that "return" is such an appallingly bad name for that operation that i can only imagine it was chosen as a placeholder that never got fixed (like most functional language and library "design")
|
# ? Feb 19, 2017 08:55 |
|
yeah, 'return' is badly named and trips up people every single loving time String showing up as [Char] in error messages isn't good either last time i checked you got a pretty unhelpful error message for doing this too: 'c' ++ "butt" e: i didn't even notice the 'do' lol e2: this is what you want: wtf :: String -> String wtf str = "wtf: " ++ str only use 'do' and 'return' when you're doing IO (to start with) gonadic io fucked around with this message at 09:03 on Feb 19, 2017 |
# ? Feb 19, 2017 08:56 |
|
rjmccall posted:the first is that the consensus call syntax in non-sexpr functional languages is terrible bullshit that trips newcomers up brutally all the time What is this? rjmccall posted:the third is that "return" is such an appallingly bad name for that operation that i can only imagine it was chosen as a placeholder that never got fixed (like most functional language and library "design") I think the motivation for this was to write cute imperative-like code. "See, it even ends with a return, like in C!" Agreed it is stupid, and most Haskell people think it is stupid, too. But functional languages are good and pretty.
|
# ? Feb 19, 2017 10:00 |
|
I'm probably gonna keep it around as an alias or whatever, but pure is the much better name.
|
# ? Feb 19, 2017 10:04 |
|
someone explain do syntax to me please 😁
|
# ? Feb 19, 2017 10:19 |
|
it's monads. nothing but monads
|
# ? Feb 19, 2017 10:27 |
|
Shinku ABOOKEN posted:someone explain do syntax to me please 😁 yeah it's used for threading monad computations. in a gross simplification you can use it to "get" a value out of a monad (usually IO) to do stuff with it the restriction is that the thing you want to return has to be in the monad too. so if the last thing you do is like printLine which returns "IO ()" then you're fine and don't need return: code:
however if you want to return a pure value from a do-block then you need to wrap it in return. there is NO other use case for return until you're using more complicated monads code:
i can't really think of any use for do-notation other than for IO ffor beginners. it technically works with lists and options and stuff but imo don't use it until you know how it works behind the scenes i'm happy to do a post on what it actually means if people want (all continuations all the time), but this is a crash course into how to use it without looking like an idiot. in short: it threads around values from IO. it's syntactic sugar so "<-" is not a function with a type or anything. gonadic io fucked around with this message at 12:09 on Feb 19, 2017 |
# ? Feb 19, 2017 12:05 |
|
gonadic io posted:yeah it's used for threading monad computations. in a gross simplification you can use it to "get" a value out of a monad (usually IO) to do stuff with it does do notation get any special treatment in the compiler/type system? from what i understand it's 100% sugar. also does any other func lang have something similar?
|
# ? Feb 19, 2017 12:52 |
|
Shinku ABOOKEN posted:does do notation get any special treatment in the compiler/type system? from what i understand it's 100% sugar. nope*, gets compiled into using the standard method >>= scala's for-comprehensions and f# computation expressions suit the same need, it comes up when you're e.g. playing around with futures and find yourself with code that chains computations like (in rust) get_butt().and_then(|butt| butt.get_fart().and_then(|fart| ...)) for an example of doing this in c++ see https://bartoszmilewski.com/2014/02/26/c17-i-see-a-monad-in-your-future/ *: okay yes technically but it's only a tiny tiny hack when it's used with $ to make stuff like code:
gonadic io fucked around with this message at 13:04 on Feb 19, 2017 |
# ? Feb 19, 2017 13:01 |
|
gonadic io posted:i can't really think of any use for do-notation other than for IO ffor beginners. it technically works with lists and options and stuff but imo don't use it until you know how it works behind the scenes Do-notation is super widespread and super useful for all monadic Haskell code, even if it doesn't use any IO. I've written a 40k SLOC Haskell program that has no IO apart from initial and terminal faffing about with files, and I use do-notation all over the place. I would never use do-notation in a teaching context, though. It obscures what's going on.
|
# ? Feb 19, 2017 16:37 |
|
Athas posted:Do-notation is super widespread and super useful for all monadic Haskell code, even if it doesn't use any IO. I've written a 40k SLOC Haskell program that has no IO apart from initial and terminal faffing about with files, and I use do-notation all over the place. what monads? list, maybe, state, and then your parser of choice?
|
# ? Feb 19, 2017 16:41 |
|
Ator posted:i went with haskell because new irl friend is also learning the language with me if they're really old they use rexx
|
# ? Feb 19, 2017 16:51 |
|
Vanadium posted:in my hubris i keep writing shell scripts that inevitably grow to the point where I want to say "ok and now spawn a couple threads and then use channels to combine the results again" and then it turns out bash isn't go fork a couple subshells which write to some fifos and then cat the results together maybe? i did something similar recently to pipe a sample video to three x264 processes with different compression settings (although in this case the processes read from a single input pipe that was tee'd to the fifos, rather than the other way around) it worked alright, though you do wanna keep track of those pids to know when they've finished using "wait"
|
# ? Feb 19, 2017 17:59 |
|
Athas posted:What is this? most core design decisions in functional languages are made by academics who are way more interested in the underlying ideas than they are in the implications for the usability of the language the call syntax, where you just juxtapose the function and its arguments, is really pretty in simple cases, but it isn't something programmers will have seen in other languages, and it isn't common in math notation (outside of trigonometry). so when novices try to use it they write stuff like "foo hd:tl" or "foo bar(baz)" and get inscrutable errors because the mistake is really a mis-parse, not anything semantic. the second one is particularly bad because the programmer probably thinks they've disambiguated it by "not leaving out the parentheses". to be fair, this is all worse in ml-derivatives than in haskell because they don't emphasize currying so much and so the one-argument unparenthesized call feels more like a special case and haskell doubles down on it by adding $ into the mix so experts can avoid parentheses even more while novices have even less of an idea what's going on
|
# ? Feb 19, 2017 18:15 |
|
currying all over the language and library is a sure sign that it is designed by someone far too busy with how clever they are to think about what a program will look like
|
# ? Feb 19, 2017 18:22 |
|
i've asked and never seen an example of haskell in the wild. i have no concept of what lob haskell looks like.
|
# ? Feb 19, 2017 18:26 |
|
"functional" languages are not designed for programming, they're designed for academic exercises. theres no such thing as lob Haskell
|
# ? Feb 19, 2017 18:29 |
|
rjmccall posted:most core design decisions in functional languages are made by academics who are way more interested in the underlying ideas than they are in the implications for the usability of the language you're a really smart dude and basically everything that I want to be, but I have to disagree it's true that "it isn't something programmers will have seen in other languages", but that's a really scary, bad precedent to set as a rule for language features, especially because with any other syntax currying is absolute trash unless you special case stuff everywhere and I don't think that "oh, just have func(x, y, z) be func(x)(y)(z) is any better, since it's not like func(x, y) :: z -> a is less startling. honestly, it should be different because it is fundamentally a different operation than procedural language function calls. it's not loading stuff into registers and then using your architecture's equivalent of call/ret at a conceptual level, term rewriting implementations aren't used because of terrible performance but the fact it is an actual function call is just an implementation detail of no direct relevance to a programmer who is unfamiliar enough to get tripped up by that syntax.
|
# ? Feb 19, 2017 18:58 |
|
currying is a silly gimmick at best and makes your code too spicy (unreadable, useless) at worst
|
# ? Feb 19, 2017 19:19 |
|
I think currying owns and I miss it (at least in its convenient form) every time I'm coding in languages like C++. v0v
|
# ? Feb 19, 2017 19:57 |
|
Blinkz0rz posted:i've asked and never seen an example of haskell in the wild. i have no concept of what lob haskell looks like. code:
there u go
|
# ? Feb 19, 2017 19:58 |
|
let's just ask our favourite non-biased source, the haskell wiki https://wiki.haskell.org/Haskell_in_industry
|
# ? Feb 19, 2017 20:07 |
|
lol Bump
|
# ? Feb 19, 2017 20:09 |
|
gonadic io posted:what monads? list, maybe, state, and then your parser of choice? In larger Haskell programs, you usually construct stacks of monads to support whatever effects you need for the task at hand. Each stack is a unique monad. A combination of Maybe (or some other error monad), Reader, and State is pretty common. Just today I worked on a type checker that was a composition of six or seven monad combinators (separated into two distinct layers - it's confusing if you have two visible layers that expose similar effects). And then you get to write code like: code:
rjmccall posted:most core design decisions in functional languages are made by academics who are way more interested in the underlying ideas than they are in the implications for the usability of the language While I'm totally an ivory tower academic, I'm working on a language myself, and I care a lot about making the language usable for others. I thought a lot about the issue of function call syntax, and eventually opted for picking the usual functional application-by-juxtaposition notation. You're right that it's alien to some, but it's conceptually quite simple in a pure language, because application is just substitution (modulo strictness). And given that FP is (slowly) gaining ground, an increasing number of programmers will have seen something like this in Scala or F# or whatever is the vanguard these days. Most of your concerns are about new programmers. That's pretty reasonable, but I don't think a language design should optimise primarily for programmers who are new to the language, as most won't stay that way for long. Ultimately, the main reason I ended up making most of my syntax decisions was that I felt I couldn't be sure of the quality of the design unless I designed a language that I would want to use. I have little idea how to judge what other people find cool and good, so I just tried to keep it both simple and pretty according to my own sense of aesthetics. The application-by-juxtaposition notation does have one problem, in that it can be tricky so support usual a[i] array index notation. Most functional languages would see a[i] as applying 'a' to the singleton list '[i]'. In my case, I solved it by treating it specially in the parser when there is no space between a name and an opening bracket. F# solves it by requiring you to write a.[i] I think.
|
# ? Feb 19, 2017 20:18 |
|
Athas posted:I have little idea how to judge what other people find cool and good, so I just tried to keep it both simple and pretty according to my own sense of aesthetics. good enough for ruby, good enough for you
|
# ? Feb 19, 2017 20:28 |
|
Sinestro posted:honestly, it should be different because it is fundamentally a different operation than procedural language function calls. it's not loading stuff into registers and then using your architecture's equivalent of call/ret at a conceptual level universities often teach assembly-level concepts at the same time they teach c because c has a relatively straightforward compilation model and abi, meaning students can really easily see how the c code they write corresponds to what the compiler produces, not because that's literally the level at which semantics are defined for procedural languages. you could do the same thing for any compiled language, but you'd have to explain a lot more about (say) haskell than you would for c, like why the compiler seems to be assuming strictness here and not there. anyway the point is you can write a naive interpreter for c, it would just create a lot more mutable reference cells than a naive interpreter for ml would, because surprise it's an imperative language. the main difference between c semantics and functional semantics beyond mutability is just that c has a lot of undefined-behavior rules to allow a more efficient implementation, but that is an intentional choice, not a consequence of c really being defined in terms of a naive lowering to assembly actually it's a fairly regular source of annoyance to (some) systems programmers that c has high-level semantics which compilers can use to optimize allocations, memory accesses, calls, etc.
|
# ? Feb 19, 2017 22:10 |
|
Athas posted:While I'm totally an ivory tower academic, I'm working on a language myself, and I care a lot about making the language usable for others. I thought a lot about the issue of function call syntax, and eventually opted for picking the usual functional application-by-juxtaposition notation. You're right that it's alien to some, but it's conceptually quite simple in a pure language, because application is just substitution (modulo strictness). And given that FP is (slowly) gaining ground, an increasing number of programmers will have seen something like this in Scala or F# or whatever is the vanguard these days. i mean, it's your language, it's your taste, don't mind me. i don't see what the simplicity of application being substitution (as if this is somehow untrue of other languages?) has to do with the syntax, though, since notably mathematics has literally no concept of evaluation and seems to get along just fine with f(x) i agree that partial application is very clean with juxtaposition, but i also tend to think that functional programmers (1) over-estimate how often they're actually partially applying functions, probably due to cognitive bias, and (2) wildly over-use point-free style, which was never intended to be actual programming advice as opposed to an interesting mental exercise
|
# ? Feb 19, 2017 22:20 |
|
the fsharp pipelining operator makes partial application really common, useful and readable fwiw
|
# ? Feb 19, 2017 22:31 |
|
|
# ? May 22, 2024 08:51 |
|
how often is it really partial application vs. non-application? alternatively, how often are you really using arbitrary functions instead of map/filter/whatever which could be designed for this use-case? also if you really wanted to make partial application easier it wouldn't be hard to add syntax like f(_,x), and then it even works for an arbitrary argument
|
# ? Feb 19, 2017 22:38 |