Live data from Hacker News

Alpaca – Functional programming inspired by ML for the Erlang VM

github.com

41–50 of 98 posts

Re: Alpaca – Functional programming inspired by ML for the Erlang VM

#41

Earlier quoted context omitted.

I haven't used Elm yet, but if you like it, check out the language it is implemented in, Haskell

I've been trying to crack Haskell for a while, but didn't find it approachable at first. Somehow Elm and building simple web apps made grasping FP easier. So now that I've learnt a bit of Elm, I find I can grasp Haskell more and spend a bit playing with. The best part is, after reading this [0] I'm finally grasping Monads. [0] http://adit.io/posts/2013-04-17-functors,_applicatives,_and_...

I learnt more about Haskell in ten days of using Elm than I would have in another ten days of studying Haskell, personally.

I think Elm makes a better introduction to FP concepts because there's much less you have to absorb before you reach the point where you can start practicing by doing useful work. Obviously part of that is the fact that Elm removes or hides certain things Haskell has, but an even bigger reason is that you can just say "...and then 'main' returns the HTML element or Html.program that actually gets displayed" and not have to go down the road of IO actions, functors, etc. You can stop at that point and start making working useful applications while getting comfortable with immutability, purity, the type system, and control flow and iteration under those constraints.

Learning Haskell first, you don't have that opportunity to stop and start practicing. You need to move on an understand at least IO actions, functors, applicatives, typeclasses, and other higher-level concepts before you can construct even a simple practice project. Dreaming up a coherent program structure/flow in this weird new immutable and pure world seems hard enough to a beginner without also having to understand how applicative functors fit into the equation. Having that opportunity to stop and stretch your legs by actually doing a project is a major help to a lot of people, that's what makes all the difference. And then 95% of what you've learned transfers directly into Haskell.

Re: Alpaca – Functional programming inspired by ML for the Erlang VM

#42
post #28
post #21

Earlier quoted context omitted.

> everything that uses that type is statically checked to be "behind" that gateway In a distributed system, the largest the "gateway" can reliable be is a single node, because you don't get guarantees about the code that other nodes in the system are running. Even the single node case poses difficulties, because I believe in OTP the upgrade path means you have to transfer state during upgrades. What if the types of t…

'Sure, you can receive messages as "Object" and then cast/parse them inside the node. Does that mesh with the vision of what people have when they want to bring static typing to erlang?' No, that's not how you do it. You marshal things directly into the desired types. Check out either aeson for Haskell or how Go does things via either the json modules or the generic Text/Binary Marshaler/Unmarshaler. "but also the my…

After using hot code loading in production for the last 5 years, I don't see why you wouldn't use it, when it's right there. Maybe it's less thought to do a rolling restart, but it's a lot more effort expended by everything in the system to rebuild all the state that was in your processes.

A behavior is simply a list of functions you've declared that your module will export -- and a convention on what they might do. gen_server.erl is going to make lots of callbacks into your code, and rather than pass a huge list of funs, instead we pass the module name, and gen_server calls the exported functions from that module (this style means all the callbacks will hit your new code if you hot load, without you doing anything special; processing type changes is up to you, of course)

Re: Alpaca – Functional programming inspired by ML for the Erlang VM

#43
post #19
post #6

Earlier quoted context omitted.

Would you mind elaborating, or sharing some papers on the subject? I'm particularly interested in a dialect of ReasonML that would use the BuckleScript compiler + ConcurrentML but target the BEAM VM, and I'd love to know how bad of an idea it might be. Maybe because it lacks e.g. session types it's hopeless, but I'm not sure. So, would love to hear specifics!

There are parts of OTP patterns that seem inherently dynamic. Message passing is only one aspect. There are also deployment/upgrade concerns with a running system. Actors can receive messages that change their behavior entirely ( http://erlang.org/doc/man/gen_server.html ). Features like this are not there by accident. Actors can hot-upgrade code their dynamically while the process is running. For example, if an acto…

I have version N of a struct and then having version N+1 of a struct in-flight at the same time is almost impossible with current statically typed languages. In a dynamically typed language, as long as the contents of version N+k struct are additive and don't change the semantics, old code can read new data.

What needs to happen is both, immutable code, and versioned structs with pure functions that can upgrade and possibly downgrade structs as needed. The larger the distributed system, the versions of a struct (message) will be in-flight at a time. Services need to contain no state, so that they can be micro-rebooted and brought up with the new version.

Joe Armstrong had a comment on globally accessible but immutable code, which I think would go a long way towards the ability to statically type the inputs to a function in a distributed system. Interposition and routing would be the only way to upgrade or deprecate old code paths.

Re: Alpaca – Functional programming inspired by ML for the Erlang VM

#44
post #36
post #32

Earlier quoted context omitted.

I know how aeson works, but the details of how it parses text into a HashMap that you can extract fields from into a data structure is somewhat besides the point, but I'll grant you the point that there are static solutions for message passing, sure. It seems odd to me that they would include a unique feature like live-updating if it shouldn't be used. I grant that live-updates and gen_servers may be anti-patterns, b…

I think even live-updating could be statically typed. Basically the live-update is a collection of functions that map every data type in the old process into the corresponding type in the new process. In the dynamically-typed case, these functions are just the identity. In the statically-typed case, if the new type has a new attribute, your mapping function has to define a reasonable default value. If you can't do th…

The main problem with pushing a typechecked live-upgrade in one shot is that you'll need to put a big lock around the distributed system (A non-upgraded node messaging an upgraded one would be fine, because the upgraded one knows the conversion function, but what happens in reverse scenario?)

It could be done without a big lock by splitting into three steps:

1) Push an upgrade that changes the types and adds the conversion functions. The valid type is the union of the old type and the new type. Wait until all nodes complete the upgrade.

2) Push an upgrade that instructs the nodes to convert their data and start using the new types by default. Wait until all nodes complete the upgrade.

3) Push an upgrade that removes the old types and conversion functions.

Re: Alpaca – Functional programming inspired by ML for the Erlang VM

#45
post #22
post #15

Earlier quoted context omitted.

There's always room for another language. What's hard is cracking into the very, very top tier, the C++, C#, Java, etc. tier. I am also increasingly of the opinion that it simply takes massive corporate backing to get to that level, based on the observation that I haven't seen anything get to that level without it. Python's the only one that has arguably gotten there, I think, and it's still debatable. That said, I d…

I'd love to have something that takes the best of Go (static typing, fast compiles, binaries, community) and functional paradigm.

How about Rust, no fast compile though.

Re: Alpaca – Functional programming inspired by ML for the Erlang VM

#46
post #36

Earlier quoted context omitted.

I think even live-updating could be statically typed. Basically the live-update is a collection of functions that map every data type in the old process into the corresponding type in the new process. In the dynamically-typed case, these functions are just the identity. In the statically-typed case, if the new type has a new attribute, your mapping function has to define a reasonable default value. If you can't do th…

The main problem with pushing a typechecked live-upgrade in one shot is that you'll need to put a big lock around the distributed system (A non-upgraded node messaging an upgraded one would be fine, because the upgraded one knows the conversion function, but what happens in reverse scenario?) It could be done without a big lock by splitting into three steps: 1) Push an upgrade that changes the types and adds the conv…

Why is this a limitation only of type-checked functions?

The problem is whether the function can or cannot handle the content of the new message and that's completely orthogonal

Re: Alpaca – Functional programming inspired by ML for the Erlang VM

#47

Earlier quoted context omitted.

I haven't used Elm yet, but if you like it, check out the language it is implemented in, Haskell

I've been trying to crack Haskell for a while, but didn't find it approachable at first. Somehow Elm and building simple web apps made grasping FP easier. So now that I've learnt a bit of Elm, I find I can grasp Haskell more and spend a bit playing with. The best part is, after reading this [0] I'm finally grasping Monads. [0] http://adit.io/posts/2013-04-17-functors,_applicatives,_and_...

I would recommend having a look at Purescript too. One of the very nice things about Purescript is that it generates very readable Javascript. One of the things I was always wondering about is how exactly tail call optimisation works. Looking at the output of Purescript for about 10 seconds answered any questions I had.

Also, though it has been posted here before (and I don't think it has been worked on for a while), I recommend playing with the Monad Challenges[0]. Well, specifically, just do set one (random numbers). You can easily write your own rand function that returns the seed value as a "random" number and then increments the seed. This will generate successive integers (1,2,3,4...). It makes it very easy to test. Then once you've done set one, go back and write map, apply, etc for Gen. One other nice thing you can do is to make a union type/ADT for your random number (i.e., (Int, Seed) ) and then try to see if it is a functor and applicative (also try to understand why or why not). Finally, you can figure out why Gen is structured the way it is.

I've played with that kata over and over and over again. It is simply beautiful.

[0] - http://mightybyte.github.io/monad-challenges/

Re: Alpaca – Functional programming inspired by ML for the Erlang VM

#48
post #15

Really hoping this project gets more traction. I'm learning Elm now and I'm really liking the syntax to the level that other languages feel rather cluttered to me now. The more I'm playing with types and learning to leverage them, the more I appreciate their power (yes, I'm late to the game) so making this statically typed is very interesting. However, there seem to be a saturation of new languages and not sure if th…

There's always room for another language. What's hard is cracking into the very, very top tier, the C++, C#, Java, etc. tier. I am also increasingly of the opinion that it simply takes massive corporate backing to get to that level, based on the observation that I haven't seen anything get to that level without it. Python's the only one that has arguably gotten there, I think, and it's still debatable. That said, I d…

[deleted]

Re: Alpaca – Functional programming inspired by ML for the Erlang VM

#49
post #46

Earlier quoted context omitted.

The main problem with pushing a typechecked live-upgrade in one shot is that you'll need to put a big lock around the distributed system (A non-upgraded node messaging an upgraded one would be fine, because the upgraded one knows the conversion function, but what happens in reverse scenario?) It could be done without a big lock by splitting into three steps: 1) Push an upgrade that changes the types and adds the conv…

Why is this a limitation only of type-checked functions? The problem is whether the function can or cannot handle the content of the new message and that's completely orthogonal

The difference is that attempting to add code to a live system that mishandled an input (either from a non-upgraded node or an upgraded one) would result in a type-error and reject the upgrade.

You could still use Erlang's crashing and supervisor technique, but you would have the additional benefit of using static typing across a distributed system (where each node may or may not have received the upgrade yet).

Re: Alpaca – Functional programming inspired by ML for the Erlang VM

#50
post #33

Earlier quoted context omitted.

Think of it this way: you have a struct type with 4 attributes that you want to pass to another function. Currently, that function declares it will match on the pattern of those 4 attributes rather than a static type. Now, you update the Node and modify the type on the sending Node to have 5 attributes. With pattern matching on the 4, everything still works. With static types on the struct the contract is now out of…

I find this to be a really poor argument. Essentially you're lucky if your systems continue to work as others go off changing message formats without consideration for the code that will receive it? On a suitably complex/large system this is a recipe for disaster. Things start to slowly rot. It is far better to maintain the old function, accepting the old struct, map it to the new struct and forward it on to the new…

I've worked with systems like that for years, and it's fine. We can have several large binaries with different release schedules, passing around a big struct with 50 fields and many nested structs, with different people making changes to different parts. And nothing breaks. New code accepts old structs, old code accepts new structs, no conversion code required.

To achieve that, we follow the design of Protocol Buffers:

1) Each field in each struct has both a name and a numeric id. Only ids are used for serialization, so field names can be changed at any time.

2) All fields are marked as optional or repeated, never required. Most code is written to handle missing fields gracefully.

3) Changing the type or id of an existing field is forbidden. (Note that changing the contents of a nested struct doesn't count as changing its type.)

4) Adding a new field is okay, as long as you use an id that was never used before. (Each struct definition has a comment indicating the next available id to use.)

5) Removing a field is okay if you've checked that no one is using it anymore.

6) As a small but intentional bonus, you can change an optional field to repeated while preserving binary compatibility.

In the end it works out. You can think of breakages that could theoretically happen, but they don't.

Post reply on HN