|
Asymmetrikon posted:I like Idris over Haskell because of some of the historical weirdness it got rid of (switching : and ::, returning Maybe instead of erroring in, i.e., List access functions, the whole Monad/Applicative thing, Int vs. Integer.) I haven't looked too much into GHC 8, though. xtal posted:I have a bunch of small complaints (Idris improves a lot more than the type system) but the lack of performance (String) and safety (totality) in the Prelude are what gets me. Having an opaque list type already pokes holes in type safety, so at the very least I want a Prelude that is total. Alternatives also tend to be implemented via type classes rather than concrete types which I prefer.
|
# ? Sep 4, 2016 18:19 |
|
|
# ? May 15, 2024 03:58 |
|
Sorry for the derail but I am sort of only curious about alternative preludes. It would actually not surprise me if there was one that defined operations in terms of lenses.
|
# ? Sep 4, 2016 19:40 |
|
Barnyard Protein posted:Does anyone know of a racket function/macro that does something like these clojure operators? Update: I've finally learned enough racket to be able to write the macro without thinking about it to hard.. Then I remembered I posted here about it, posting in case someone else is interested. Racket is cool. (I used the thread-last operator from clojure as to implement thread first, forgot which was which) Lisp code:
Lisp code:
Lisp code:
|
# ? Sep 8, 2016 21:59 |
|
Ralith posted:
I just wanted you to know I am really on board with lenses now. I was avoiding them because I think Template Haskell is the plague but I'm able to compartmentalize all of that junk in a Types file.
|
# ? Sep 9, 2016 16:11 |
|
xtal posted:I just wanted you to know I am really on board with lenses now. I was avoiding them because I think Template Haskell is the plague but I'm able to compartmentalize all of that junk in a Types file. You don't actually need to use Template Haskell to use lenses at all, even advanced things like biplate; the boilerplate is concise and linear wrt. your original code. The TH just saves a few lines and ensures consistency, which is enough reason for me to use it, but it's by no means unavoidable. One of the original design goals of lens was actually to allow people to easily make libraries compatible with it without even depending on the package.
|
# ? Sep 10, 2016 02:29 |
|
Ralith posted:
That's good to know, I was under the wrong impression because the first step in every tutorial is Template Haskell.
|
# ? Sep 10, 2016 03:10 |
xtal posted:That's good to know, I was under the wrong impression because the first step in every tutorial is Template Haskell. Which tutorials were you using? I've been meaning to try out lenses.
|
|
# ? Sep 10, 2016 04:36 |
|
xtal posted:That's good to know, I was under the wrong impression because the first step in every tutorial is Template Haskell.
|
# ? Sep 18, 2016 20:09 |
|
mystes posted:That's because the tutorials all start with a bunch of nested record types, and in this case it's convenient to use template haskell to automatically generate the lenses from the record fields. Otherwise the boilerplate code would be pretty verbose and probably immediately cause people to close the tutorial. So your choices are the horror of template Haskell or the horrors of boilerplate?
|
# ? Sep 18, 2016 23:53 |
|
xtal posted:So your choices are the horror of template Haskell or the horrors of boilerplate?
|
# ? Sep 19, 2016 00:05 |
|
Picked up the O'Reilly on Elixir and I'm going through it prior to trying out Phoenix. I'm kind of surprised you're allowed to mutate variables though, I thought preventing that was a core thing for functional languages?
|
# ? Oct 10, 2016 17:38 |
|
You can rebind variables, but the data itself is immutable.
|
# ? Oct 10, 2016 17:49 |
|
tekz posted:Picked up the O'Reilly on Elixir and I'm going through it prior to trying out Phoenix. I'm kind of surprised you're allowed to mutate variables though, I thought preventing that was a core thing for functional languages? elixir (stupidly) has immutable data but mutable references. you can't alter data once assigned to a reference, but you can change what data a reference refers to at any time. all function calls and message sends are pass by value tho, so the damage done in minimal
|
# ? Oct 10, 2016 18:02 |
|
Thanks. I've noticed that the O'Reilly examples for simple stuff seems to include a lot of boilerplate. For example, for calculating the product of values in a list, instead of doing something simple like:code:
code:
|
# ? Oct 10, 2016 22:04 |
|
tekz posted:Thanks. I've noticed that the O'Reilly examples for simple stuff seems to include a lot of boilerplate. For example, for calculating the product of values in a list, instead of doing something simple like: It is! Their implementation can run in constant space while yours, potentially, could blow up the stack. Check out the Wikipedia article on Tail Call Recursion/Optimization for more info.
|
# ? Oct 10, 2016 22:20 |
|
Ploft-shell crab posted:It is! Their implementation can run in constant space while yours, potentially, could blow up the stack. Check out the Wikipedia article on Tail Call Recursion/Optimization for more info. His implementation is still TCO, it just uses an if statement rather than patterns and guards. The comparison remains linear time (pattern matching can only sometimes be optimized to constant; guards never can.) This is a matter of preference but functional programmers consider if statements to be ugly and imperative. xtal fucked around with this message at 23:27 on Oct 10, 2016 |
# ? Oct 10, 2016 23:22 |
|
the talent deficit posted:elixir (stupidly) has immutable data but mutable references. you can't alter data once assigned to a reference, but you can change what data a reference refers to at any time. all function calls and message sends are pass by value tho, so the damage done in minimal Local mutation has basically none of the disadvantages of shared/global mutation and eliminates a lot of local data-flow headaches. You should not feel bad about using it.
|
# ? Oct 10, 2016 23:50 |
|
rjmccall posted:Local mutation has basically none of the disadvantages of shared/global mutation and eliminates a lot of local data-flow headaches. You should not feel bad about using it. i get why they chose to allow rebinding references but it makes it significantly harder to catch errors when your primary flow control involves pattern matching (which uses unification not equality)
|
# ? Oct 11, 2016 00:18 |
|
rjmccall posted:Local mutation has basically none of the disadvantages of shared/global mutation and eliminates a lot of local data-flow headaches. You should not feel bad about using it. Yeah, the main benefit of functional programming is in having immutable data structures (that can be efficiently used). You can connect them together and use them more versatilely than otherwise, and are harder to screw up. It's generally a good style of software architecture. A rather nice pure functional programming language would be a version of Rust without RefCell, Cell, or other stuff that uses UnsafeCell, that lets you freeze objects onto a garbage collected heap. So you get local mutation and build arrays and can do mutable borrows. But it would also benefit from not having horrendous "let mut _:_" bullogna and also some goto statements to scare off undesirables.
|
# ? Oct 11, 2016 00:45 |
|
Is local mutation necessary with sufficiently advanced COW and GC? You don't need to bust out transients in Clojure often and I don't think Haskell even includes them. I don't think the real world performance improvement is big enough to involve mutable state; and, if you spent the time improving the implementation of your immutable structures instead, its benefits would apply to all your code implicitly.
|
# ? Oct 11, 2016 01:25 |
|
xtal posted:Is local mutation necessary with sufficiently advanced COW and GC? Depends what you're building and how important performance is? And convenience? When some people got me to do a Goog Code Jam, I first tried using Haskell, and... ick. It's much nicer to develop code rapidly with for loops, with pushing stuff onto vectors, with being able to turn a map into a fold with a variable declaration, and without having to janitor values into and out of functions into the right kind of tuple. But also imagine doing stuff where performance is important. In C++, people often disable copy constructors on a type for that reason that copies are too expensive, and they don't want to get one accidentally. If you're setting a vector element, it's relatively easy to have an accidental extra pointer to it. I mean, let's say it's in a variable and you're appending to it. v = push(v, x). Well, you'd need some semantic defined there that moves v into the parameter list of push and moves v out without bumping a refcount. That's what Rust has -- only instead of reasoning in your head about what the refcount should be, and hoping the code never evolves into something that has to copy, it's enforced by the language. sarehu fucked around with this message at 01:45 on Oct 11, 2016 |
# ? Oct 11, 2016 01:43 |
|
With those criteria I would say that GC and mutability are two sides of one coin. If you're using immutable structures you need good GC. If your performance needs are such that you can't afford immutability, you can't afford a GC either.
|
# ? Oct 11, 2016 02:00 |
|
xtal posted:With those criteria I would say that GC and mutability are two sides of one coin. If you're using immutable structures you need good GC. If your performance needs are such that you can't afford immutability, you can't afford a GC either. Not true at all. You can benefit immensely from improving absolute performance. Not all performance requirements are low-latency/low-memory-usage. You also benefit from the convenience of mutable local variables without creeping performance risk.
|
# ? Oct 11, 2016 02:03 |
|
xtal posted:Is local mutation necessary with sufficiently advanced COW and GC? You don't need to bust out transients in Clojure often and I don't think Haskell even includes them. I don't think the real world performance improvement is big enough to involve mutable state; and, if you spent the time improving the implementation of your immutable structures instead, its benefits would apply to all your code implicitly. I disagree with your premise that the purpose of local mutation is to get better performance. It certainly can give better performance, and it isn't as subject to artificial limits where the sufficiently smart implementation just isn't sufficiently smart enough and you have no choice but to rewrite it all in a completely different style, but I think the real advantage is just the ability to change what value a name is bound to without having to deeply restructure your code around it. I mean, show me a function of any real complexity and I can probably point out several places where the programmer is basically manually performing a rudimentary data-flow analysis that the compiler could easily have done instead, where it would've been much clearer had the code just been able to declare a local variable and change it instead of binding five different names to the "variable" as it evolved during evaluation.
|
# ? Oct 11, 2016 03:32 |
|
I don't really find local mutation very useful. My kind of programming (enterprise SOAy type stuff) doesn't really need super tight performance. GC pauses are occasionally worrisome though. As for reasoning about complexity: if you honestly think a local mutable variable is going to make your function simpler, then your function is probably too big, or you should just learn how to use fold, map and flatMap (or bind). I can't really see how a local mutable variable makes code simpler. There's something to be said for: maybe that's just how your brain works, and it shouldn't really matter so long as a functional interface is presented upwards. But for devs on my team, I politely decline to merge PRs with mutation unless it's very clearly needed for a very specific reason, and suggest an alternative implementation.
|
# ? Oct 11, 2016 03:51 |
|
I do like the way Elixir handles local refs - it allows rebinding of names, but the (|>) operator makes it easy to elide names of intermediate forms if you want, so you can just use whichever approach is more appropriate based on the situation. It's kind of annoying that the forms that it allows on the right hand side of the pipe are pretty limited, though (no anonymous functions is the one I really wish it would allow.)
|
# ? Oct 11, 2016 03:55 |
|
As I'm finding myself using C++ and C# for everything course and research related, I'd really like to try a functional language to give myself a breath of fresh air. I'm mainly interested in making games and interactive graphical toys. Is there a language with more robust Vulkan and OpenGL support than others? Is there any that are more suited than others for games? I know you can use F# with Unity, is that a decent choice?
|
# ? Oct 21, 2016 05:29 |
|
everythingWasBees posted:As I'm finding myself using C++ and C# for everything course and research related, I'd really like to try a functional language to give myself a breath of fresh air. I'm mainly interested in making games and interactive graphical toys. Is there a language with more robust Vulkan and OpenGL support than others? Is there any that are more suited than others for games? I know you can use F# with Unity, is that a decent choice?
|
# ? Oct 21, 2016 05:51 |
|
everythingWasBees posted:As I'm finding myself using C++ and C# for everything course and research related, I'd really like to try a functional language to give myself a breath of fresh air. I'm mainly interested in making games and interactive graphical toys. Is there a language with more robust Vulkan and OpenGL support than others? Is there any that are more suited than others for games? I know you can use F# with Unity, is that a decent choice? I don't use unity but since f# gives.you access to everything c# as well you have got good bindings such as opentk or even sfml if you want something more comfortable
|
# ? Oct 21, 2016 06:05 |
|
everythingWasBees posted:As I'm finding myself using C++ and C# for everything course and research related, I'd really like to try a functional language to give myself a breath of fresh air. I'm mainly interested in making games and interactive graphical toys. Is there a language with more robust Vulkan and OpenGL support than others? Is there any that are more suited than others for games? I know you can use F# with Unity, is that a decent choice? Unity will not have the latest version of F#. You're constrained to something about .Net3.5. It's also a bit onerous to set up last time I tried it. It's not a terrible choice.
|
# ? Oct 21, 2016 14:55 |
|
leper khan posted:Unity will not have the latest version of F#. You're constrained to something about .Net3.5. It's also a bit onerous to set up last time I tried it. It's not a terrible choice. IIRC the latest Unity beta uses .Net 4.6 or something like that (of course then you're using a beta release, and all the fun that comes with that)
|
# ? Oct 21, 2016 15:03 |
|
Ralith posted:Are you looking to do low level or high level gamedev? OpenGL (let alone Vulkan) won't come up much in Unity. Bit of A, bit of B. If there wasn't good support then I'd just go with Unity in general, as it allows a surprising amount of graphics fuckery if you sidestep a lot of the default systems. netcat posted:I don't use unity but since f# gives.you access to everything c# as well you have got good bindings such as opentk or even sfml if you want something more comfortable This sounds really appealing. F# it is. Thank you all!
|
# ? Oct 21, 2016 16:48 |
|
There's also Vulkan bindings for Haskell and apparently people have done stuff to incorporate post OpenGL 3.0 style code into Haskell too. Vulkan is actually surprisingly nice to use from Haskell because it doesn't have all of the implicit state bullshit that OpenGL has.
|
# ? Oct 23, 2016 21:56 |
New version of Elm is out.
|
|
# ? Nov 15, 2016 07:44 |
|
Glad they finally got the time-traveling debugger working the way they wanted it to.
|
# ? Nov 15, 2016 14:34 |
|
VikingofRock posted:New version of Elm is out. quote:Primes — Names like x' are no longer permitted. but... but... but... I liked my primes
|
# ? Nov 15, 2016 18:22 |
Shinku ABOOKEN posted:but... but... but... I liked my primes Me too! I also liked the [1..5] syntax and back ticks. I suppose I can see the argument for removing all three though.
|
|
# ? Nov 15, 2016 20:27 |
|
VikingofRock posted:Me too! I also liked the [1..5] syntax and back ticks. I suppose I can see the argument for removing all three though. The [1..5] syntax was nice, but I'm not too put out by losing it. Backticks I could go either way on, I can definitely see the simplicity of just encouraging |>. Good riddance to x' style variable names though, they're awful and don't communicate anything meaningful. But then, I also hate point-free style, so I'm somewhat out of step with a lot of Haskellers anyway.
|
# ? Nov 15, 2016 20:39 |
|
Arcsech posted:The [1..5] syntax was nice, but I'm not too put out by losing it. Backticks I could go either way on, I can definitely see the simplicity of just encouraging |>. They made a pretty big breaking change, though, to encourage use of |>. (x `andThen` y) translates to (andThen x y), but (x |> andThen y) translates to (andThen y x). They had to flip the argument order of andThen to support this change, which I think is pretty bold. e: luckily the argument types are incompatible, so it's not possible to compile code that was broken this way. Bognar fucked around with this message at 20:50 on Nov 15, 2016 |
# ? Nov 15, 2016 20:46 |
|
|
# ? May 15, 2024 03:58 |
|
Making "x |> andThen y" canonical matches with the way all other functions work (the entity they operate on is the last input to the function), so I'm happy about that. I really like the error improvements, especially making type annotations provide more context to errors.
|
# ? Nov 15, 2016 20:56 |