6 ms·
Elixir Streams
- _nato_ 11y agoI wonder what the Erlang equivalent would look like (passing around data that are funs)?
- davidw 11y agoI'm mostly an Erlang guy, but I do like that about Elixir: they really seem to be taking the Erlang base, and building on it in some interesting ways.
- mjs2600 11y agoThat's the macros. Phoenix's routing is an awesome example of the power of Elixir macros. It leverages the BEAMs pattern matching capabilities to do the routing, but the syntax is very clear and concise.
- Skinney 11y agoMinor nitpick. BEAM doesn't have pattern matching built-in. Core Erlang does. Core Erlang compiles to BEAM bytecode with functions using regular if-statements. So basically: Erlang/Elixir -> Core Erlang -> BEAM. (Actually, I think there is one more step there).
- asonge 11y agoMinor nitpick to the nitpick, since I dug down in Elixir's compiler before. Elixir spits out a normal Erlang AST, not a Core Erlang AST, which is a bit different. There are a half dozen levels between the Erlang AST and BEAM as well. There's several instances of a talk by Robert Virding about implementing languages on the BEAM where he talks about which advantages different levels of the compiler to hook into.
- mononcqc 11y agoThe closest thing I can think of outside of using funs or macros to define the usual `delay` and `force` operators, and that currently exists, would be something like the QLC interface, which allows you to turn whatever you want into a type that can be used in list comprehensions and functional queries around it: http://www.erlang.org/doc/man/qlc.html http://www.erlang.org/doc/man/qlc.html
- phamilton 11y agoWhen people say Elixir is just syntactic sugar on top of erlang I point them to Stream and Enum. It's a great example of how polymorphism via protocols is an enabler for powerful designs.
- MCRed 11y agoElixir is so much more than syntactic sugar... but you can't deny that it's also very, very sweet. I think it's the best language out there-- the power of erlang and OTP and the fun of, well, elixir. It's more fun than Ruby and Python.
- rozap 11y agoThat's the best way to describe it. The concurrency model and metaprogramming bits mean that effortless to make cool stuff with it. And it turns out that's way more fun that wrestling with the jvm or other high friction tools. There's a lot of neat stuff in Elixir, and the community is great too. I honestly it may be the first functional language that becomes widely used. Hopefully.
- doomrobo 11y agoInteresting to see this as a novel thing in another ecosystem. Rust actually uses "stream" manipulation as a default way of dealing with things that might otherwise be expressed as full data structures. For example, the equivalent to one of the code snippets in the article would be: BufReader::new(File::open("myfile.txt").unwrap()) .lines() .enumerate() .map(|(i, line)| format!("{}: {}", i, line.unwrap())) .take(1) .next().unwrap() (formatted for non-monospace font readability). Note the .unwrap() is where error handling should normally happen.
- meowface 11y agoThe problem with "stream/generator as default" is the boilerplate you constantly have to add. In Python 3, for example, map() returns a generator. So you can no longer transform a list into another list with `new = map(func, lst)`. You have to do `new = list(map(func, lst))`. One of the most subtle gotchas when upgrading from 2 to 3 is having to wrap list() around functions and methods like map(), range(), dict.items(), etc. Discussion I've seen about Rust on less moderated websites often seems to make fun of the .unwrap() spam seen in a lot of programs, to the point of the mockery even dominating some discussions. Streams and lazy evaluation are really nice, but sometimes you just want some nice procedural handling.
- Jweb_Guru 11y agoWhen using Rust for more than toy programs (which, assuming I am thinking of the same "less moderated" websites that you are, is unlikely to be the experience of the commenters), unwrap() isn't particularly common outside of main(). You generally want to handle the error cases. It's used a lot in examples because they have to function as one-offs.
- icebraining 11y agoAll the boilerplate you need to add is lmap = lambda f, l: list(map(f, l)) somewhere in your project, then use new = lmap(func, lst)
- Willyfrog 11y ago