I think some people are slightly overreading the text. I think the key idea is not that dynamic languages are going to actively die, but rather the following:
> This is my bet: the age of dynamic languages is over. There will be no new successful ones.
Emphasis mine (original emphasized the second clause of the first sentence).
Let's see... of the up-and-coming languages, the only one I can think of that might disprove that statement is Elixir. Everything else I can think of as "up and coming" is static.
July: July (excuse the lack of a readme, it's one of my next priorities) is an interpreted dialect of Lisp that I have been working on for a couple of weeks. I wrote a smaller version of the language a few months ago but I didn't feel satisfied and wanted to start over. The language is implemented in Elixir and the standard library is implemented in a combination of Elixir and July. The language is still quite bare but it's functional enough to challenges at this point. The language is heavily inspired by Scheme, Clojure and Elixir itself. It has |>
for composing functions and arity overloading
for dispatching to different logical paths and implementing functions with default arguments.
I haven't wrote evaluation from files yet, so I solved the challenge directly in the July repl (SCREENSHOT):
iex(1)> July.Repl.JulyRepl.start_repl July REPL (exit) to quit july@repl(1)> ; [2015-10-19] Challenge #237 [Easy] Broken Keyboard (/u/jnazario) july@repl(2)> ; LANGUAGE: July, AUTHOR: /u/hutsboR july@repl(3)> (import 'inou) july@repl(4)> (import 'coll) july@repl(5)> (import 'str) july@repl(6)> (defun longest-word ([word word-list] (|> (filter word-list (fun [w] (all? w (fun [c] (member? word c))))) (max-by len) (join)))) july@repl(7)> (defun get-longest-word ([] (let ([words (|> (read-file "words.txt") (split) (map str->chars))] [input (map '("edcf" "bnik" "poil" "vybu") str->chars)]) (map input (fun [word] (longest-word word words)))))) july@repl(8)> (get-longest-word) ("deeded" "bikini" "lollipop" "bubby")
Elixir is a functional, meta-programming aware language built on top of the Erlang VM. It is a dynamic language that focuses on tooling to leverage Erlang's abilities to build concurrent, distributed and fault-tolerant applications with hot code upgrades
Lens is a great example of the kind of docs I love. However, standard Haskell libs seem to be somewhat lacking.
For example, take a look at Haskell's Data.List: https://hackage.haskell.org/package/base-4.8.1.0/docs/Data-List.html . For people familiar with FP, all of these definitions might be straightforward and understandable, but for people coming from an OO background, examples would explain a lot.
If you'd like to see a good example of this, I'd suggest you to take a look at Elixir's list docs: http://elixir-lang.org/docs/stable/elixir/List.html .
This is exactly what makes Elixir so accessible IMO, and makes it harder for Haskell to get accepted by the masses. People read the explanation, don't understand the concepts mentioned, and need to start googling. A simple example sometimes makes way more sense.
Hope this doesn't become annoying when trying to find documentation:
https://laravel-news.com/laravel-elixir-to-laravel-mix
http://elixir-lang.org/getting-started/mix-otp/introduction-to-mix.html
:P
It only proved itself by running in a router twenty years ago? What about WhatsApp? Or FB Chat? Ericsson still uses erlang in a lot of places and so do other telecom places.
Maybe it is here-and-there usage but I think elixir is starting to change that. It fixes a lot of the problems you mention people have with erlang and you still get all of the erlang benefits.
Personally I never found the syntax / issues with erlang to be that much of a hindrance - once you get used to it it is very easy because the language itself is quite small.
You should definitelly look at Elixir. It's a very cool, a bit young, language based on the Erlang's VM. I'd call it an Erlang with much better syntax. It inherits all the distributed features from Erlang and is so pleasant to use. The tooling is quite good and the docs are so as well. There is a very nice web framework called Phoenix available for Elixir. It's also getting popular in the embedded world thanks to the Nerves Project.
["Admin": "admin", "User": "user"]
This is actually a keyword list. It's a list of 2-element tuples. It's syntactic sugar for:
[{:Admin, "admin"}, {:User, "user"}]
Note that the keys are atoms, not strings.
To create that using Enum.map, you want to return a tuple from your enumerator function, of the form {key, value}
.
More info here: http://elixir-lang.org/getting-started/keywords-and-maps.html
> For concurrency: see Go.
Another good option that's been gaining a lot of traction lately: Elixir and its web framework Phoenix. Elixir is functional rather than imperative (Go) and actually has a nice community. Go's community is shit and filled with people who think they're smarter than everyone else for using a "systems" language. It's filled with excessive sexism, vitriol, and close-mindedness.
This is not a for loop. This is a list comprehension. It's like a for loop on steroids. You want to check out this link for more details.
They are working on it. Last I heard that they were figuring out a way to apply back pressure to avoid messages piling up at a bottleneck.
I also like to point to: Enumerables and Streams, it gives a nice overview of how the pipe operator can be used to do lazy evaluation.
We prefer the use of doctests in crutches (when applicable), since it lends itself nicely to the design pattern. They run like normal tests. 'mix test' is showing over 150 tests.
http://elixir-lang.org/getting-started/mix-otp/docs-tests-and-pipelines.html#doctests
Check out Elixir. The =
operator is for pattern matching, not assignment. A sample IEx session showing off some pattern matching abilities, with the first interesting case at iex(4)>
:
iex(1)> x = 1 1 iex(2)> y = 2 2 iex(3)> z = [x,y] [1, 2] iex(4)> [_,b] = z [1, 2] iex(5)> b 2 iex(6)> m = %{p: z, q: 5} %{p: [1, 2], q: 5} iex(7)> %{p: v} = m %{p: [1, 2], q: 5} iex(8)> v [1, 2] iex(9)> %{q: w} = m %{p: [1, 2], q: 5} iex(10)> w 5 iex(11)> s = "Hello r/ProgrammingLanguages" "Hello r/ProgrammingLanguages" iex(12)> <<c, cs :: binary>> = s "Hello r/ProgrammingLanguages" iex(13)> c 72 iex(14)> cs "ello r/ProgrammingLanguages" iex(15)> <<"ello", cs :: binary>> = cs "ello r/ProgrammingLanguages" iex(16)> cs " r/ProgrammingLanguages"
This combined with Elixir's case
makes it easy to ingest data in appropriately sized pieces.
&
is called the capture operator, it's a different way to create anonymous functions.
&String.length/1
is the same as &(String.length(&1))
is the same as fn x -> String.length(x)
. And yes, it means use the function length
with arity 1
from the module String
(and pass that argument too while you're at it).
More info: http://elixir-lang.org/docs/stable/elixir/Kernel.SpecialForms.html#&/1
I recommend: http://elixir-lang.org/getting-started/basic-types.html#anonymous-functions
I have not learned Erlang, but am familiar and comfortable using the erlang stdlib/dist modules from within elixir.
http://erlang.org/doc/apps/stdlib/
Many Erlang modules have not been wrapped as elixir packages, and for good reason, it's totally overkill.
I've been using the Erlang zip module in a recent project for example. To accomplish certain things in elixir it is recommended to use the stdlib erlang module from within elixir.
http://elixir-lang.org/getting-started/erlang-libraries.html
Not at all!
You can get started today by reading the excellent official guide or one of the numerous books.
I'm the creator :) We've put months of work into our guides and they are your best bet to getting started with Phoenix: http://www.phoenixframework.org
If you are new to Elixir as well, the Getting Started guides at http://elixir-lang.org/getting-started/introduction.html are excellent. I also gave an Elixir workshop at RailsConf last year that was geared towards Rubyists: http://www.chrismccord.com/blog/2014/05/27/all-aboard-the-elixir-express/
> I've managed to rewrite something from ruby to crystal and got over 6x speed improvement in production!
This is a pretty useless comment without even a link to a gist.
And... oh jesus it's yet another new language. Call me jaded for being a bit fatigued by this. I'm sorry but (IMHO) if it doesn't have immutable data and isn't functional then it's eventually going away. Been doing OO Ruby for 15 years now, it leads to too much app complexity via holding onto state everywhere. And without immutable data, your concurrency is going to deal with a lot of locking, and locking is crap (if there's another way... which is immutable data... in an era of cheap memory, it finally makes more sense).
And of all the things to bring into Crystal from Ruby that should have been dropped... Global variables. Seriously? Is it 1982 on the Commodore PET in BASIC again?
I kind of wish more developers would get behind fewer projects. I've been very happy with Elixir (also ruby-like) and it already has the entire Erlang standard library behind it, which is a pretty good bootstrapping, as well as being 2-10x as fast as Ruby, as well as having sub-microsecond process spawning (great for handling new web requests), a great process management API built-in called OTP (great for uptime), immutable data, pattern matching (although I see Crystal has that too, although I'm not yet sure how sophisticated it is), functional paradigms, mainly dealing with data in a few very-well-optimized types, and all that which I have learned are Good Things™ for maintainable code. I think it's the way forward for reliable, concurrent server-side coding, not another OO lang with mutable vars.
Not sure what he's going to say but here's my latest reason (besides the long JVM startup time):
Fork/Join setup in Java; it takes many many milliseconds to fork so forking is typically only recommended to parallel-compute pools of data a million elements or larger.
Task.async in Elixir (which takes advantage of underlying Erlang facilities). It's as idiot-proof as it can get. Time to spawn a concurrent node: 1 millisecond.
this is the part where I plug elixir as something else to keep an eye on, it's also gathering steam and Dave Thomas' book on it is pretty awesome. I've been playing with it and love it so far. I've been experimenting and answering typical programming problems with it. I hope to get some paid work in it soon...
I looked at Clojure for a bit... Other than Rich Hickey being awesome, a few things immediately turned me off:
1) Having to fire up the java VM to do anything, which takes a few seconds... this is bad for the unit-test-iterative style development that I do
2) I multiplied 2 big numbers and it blew up and I got a big nasty Java stack trace. Gross. (Ruby and Elixir autoswitch to bignum.)
3) General dependence on Java. It peeks through the cracks way too much. Perhaps this was done in the interest of speed (and being able to take advantage of the many Java libraries available), but I don't want to have to deal with TWO entirely different languages when I debug. One is hard enough.
4) Some people love Lispy syntax (or lack of any syntax, as it were), I'm not in that camp. That's a taste thing, though.
According to the docs for Supervisor.Spec, the only current difference is the value passed for the :shutdown
option.
A supervised child defined with the worker
spec is given 5000ms to shutdown before being killed; the supervisor
spec sets a timeout of :infinity
, allowing as much time as necessary for the child to shutdown - including shutting down its own supervised children.
I went to backend because I hated frontend. I love backend now.
I think it depends on the reasons you hate it. I hated "F5 debugging," the having to manually test everything, the constant trial and error. (Other people like the fact that you see your work and can show it to others, which is fair.) On the backend, everything is testable, and tests are automated (well, once you write them... Which ends up being a good and valuable exercise), and shit either works or it doesn't (i.e. it's "deterministic"). To me it's a much saner mode of development. Make changes, run a test, fix broken tests, go home with a clear conscience, win. You can point people to a site and while you can't say "I designed that," you CAN say "I made that actually work".
But if you hate coding itself and problem-solving itself, then there's nothing wrong with trying different kinds of work. Don't feel bad.
Disclaimer: I did a Drupal project and fucking hated it. No access to database schema, no check-in of code, no state management access, no division between "development" and "production" modes, no nothing of that sort. If you had to do ANYTHING custom, you were basically on your own. It was weird, and vulnerable to breaking constantly. (To some extent this is PHP's fault. I also hate PHP. I love Ruby and Elixir, though. Those 2 languages alone make PHP look like a deformed red-headed stepchild, I'm sorry. I'm serious though, if you hate programming, it might be because of PHP. Try other languages, climb some learning curves.)
This is a rather complicated area about which entire books can be written, but here is the gist of it.
An OTP application's head is a special application process. Management of application processes involves a different set of options to describe what should happen when the application process crashes. (see the Documentation for more info). Generally this means either doing nothing, or crashing the whole node which can then be restarted by the OS should you desire it. This is all in line with the 'let it crash' philosophy.
The way you protect against this sort of thing happening is you run multiple nodes, hopefully on separate pieces of hardware. Then one node crashing doesn't crash your entire service.
How many workers are we talking about? 100, 100.000? If many, spread them over multiple supervisors.
Simply start an empty supervisor, and expose a public function called attach_child_process or whatever, in that function call http://erlang.org/doc/man/supervisor.html#start_child-2 http://elixir-lang.org/docs/stable/elixir/Supervisor.html#start_child/2
But be careful, you can only use simple_one_for_one supervisor restart strategy if you're appending children dynamically.
In handle_call({:add_message.... you need to capture the second parameter (from), and store it in the state. Then you can return noreply, as you are currently doing.
Later, when you are ready to reply, you can call GenServer.reply with the "from" that you captured here. Does this make sense?
It's described briefly here:
http://elixir-lang.org/docs/stable/elixir/GenServer.html#c:handle_call/3
"Returning {:noreply, new_state} does not send a response to the caller and continues the loop with new state new_state. The response must be sent with reply/2.
There are three main use cases for not replying using the return value:
To reply before returning from the callback because the response is known before calling a slow function. To reply after returning from the callback because the response is not yet available. To reply from another process, such as a task."
What you can do with your Cache module is have it use GenServer. You can then start the cache process as a child of your application's supervisor. With what you're trying to create, look into using the name
option that can be passed to GenServer.start_link
- your cache process can be registered with a name, allowing it to be accessed from any part of your code.
It seems to me that you started learning the language, you learned that recursion is how loops are done and you started implementing recursion all over the place. The first thing to know is that recursion is usually implemented in the same few ways and there are helpers which implement these patterns for you. For example, Enum.map is recursive under the hood, but it implements a very common structure where you just provide the mapping function.
GenServer is just a more rich, complicated Enum.map. It handles all of the recursion for you and you provide a set of callback functions which get called either for the lifecycle of the process, when a timeout occurs, or when a message is received. I would highly recommend reading up in the docs and guides on how GenServer works because you seem to have some fundamental misunderstandings.
You have tried to implement a one-shot GenServer which doesn't receive any messages during its lifespan. This is a common enough use-case that a helper been provided in the form of Tasks. You can start a Task as an OTP worker just like a GenServer or even do more fancy things with their supervision, but that is beyond my scope here.
Further, you seem to want to be transforming an external API call into an enumeration of elements. You should really consider wrapping this up in a Stream. Streams are, in part, designed for wrapping behavior like this to make it work like any other Enumerable. In particular, Stream.resource/3 is a good place to look.
Some combination of Task and Stream would better capture what you are trying to do here.
strings are double quoted.
iex(4)> is_binary 'abc' false iex(5)> is_binary "abc" true
char lists are single quoted
iex(6)> is_list 'abc' true iex(7)> is_list "abc" false
http://elixir-lang.org/getting-started/binaries-strings-and-char-lists/
Having become comfortable with both Erlang and Elixir, I am perhaps a bit surprised that there is much in the way of transition difficulty between the two. Unless one is metaprogramming or using the results of metaprogramming, the differences between Erlang and Elixir are trivial. Everything I say here should be prefaced by saying that I think that maintaining a project with both Erlang and Elixir code sounds like much more work than either staying with Erlang or figuring out Elixir.
Mix can compile your Erlang files in addition to your Elixir files (docs here). Erlang and Elixir don't exist in the same file. I haven't done it, but the capability is certainly there.
Modules in both Erlang and Elixir are functionally the same, they both are identified by global scope atoms, but Elixir modules use some sugar that becomes exposed when you call them from Erlang. Elixir transforms Module.Name into the Erlang-syntax atom 'Elixir.Module.Name'. To call its function foo in Erlang you call
'Elixir.Module.Name':foo().
Since Erlang modules are almost always just lower-case atoms, in Elixir you call them as
:module.foo()
I ask because I'm really liking what I'm seeing so far and I'm wondering if it's just "the initial romantic period," I'm only about a few months into FP (Elixir née Erlang) after also reading up on Haskell and Clojure and settling on Elixir ("ex"-Rubyist here). I think the various differences/improvements over OOP (pattern matching, binding vs. assignment, immutability, lack of inheritance, averse to holding onto state, and strong typing in Haskell) make FP code far more resistant to bugs and other problems while also adding features such as easy concurrency and encouraging more focused code.
Try Elixir out here. (I hope I'm not DDoS'ing it, it was slowish to load...)
Erlang has good support for TCP connections with the :gen_tcp
module (unsure of what protocol IRC uses...). The Elixir OptionParser http://elixir-lang.org/docs/stable/elixir/OptionParser.html is a good tool for CLI tools. You'll likely want to use one or more GenServers http://elixir-lang.org/docs/stable/elixir/GenServer.html as well to store state and information. Look at Task and Agent for more generic versions of a GenServer.
If I'm not mistaken, exs files compile in memory just before being run. There wouldn't be much difference unless your exs file was large enough to impact ram as it was compiled in memory.
> The file will be compiled in memory and executed, ...
>* Yay, more code to maintain but hey I will take anything if it works at this point, stalled Sharding development is a real shame when everyone is complaining about lag. Has anyone else heard of Elixir?
Based on its intended use, the maintenance of it should be pretty trivial, if not minimal. Its being made as a sort of run and forget. The plugins themselves will do most of the understanding. Its a literal router, it will just pass messages.
I also don't plan on going anywhere anytime soon. When i consider it finished Il go back through and properly comment everything down to each function. Plus perhaps an illustration of the logistics.
It's being made generic enough that any plugin can easily connect into it, along with enabling any external applications a verified path for direct bukkit plugin communication. Hell, if you'd use the api of it locally, you could have cross bukkit plugin interaction without worrying about depenacy issues with outdated plugins.
Nothing for myself, but this reminds me just the other day that a programming buddy of mine told me he's about ready to move on from Python to a functional language called Elixir that runs on the Erlang VM. I assumed he just meant for personal projects but I was wrong -- he's considering it for production. Which kind of amazed me. I don't know anything about the language, but I can't imagine it has anything like the ecosystem support as Python!
> Lisp's syntax is superior
... What syntax? ;)
Seriously though... I would kill to work with a programmer as opinionated AND informed as you. Really excellent overall assessment of the pluses and minuses.
One thing I noticed while taking "language trips" (you know, away from your day-job language, which in my case is Ruby) is that inevitably I find something I feel like I NEED in my day-job language. For Lisp it was... well, it's fucking Lisp. With Haskell it was the strict separation at the language level between side-effect-free code and side-effect-possible code (which I suppose necessitated the type system... I think? In any event, I think that being able to enforce purity at the language level is a good idea for ANY language.. Can you say "nondeterministic test suite pain"?). With Clojure it was Lisp + ClojureScript (I'm a web dev) + having a geek-crush on Rich Hickey. With Elixir/Erlang it was the concurrency and the pattern matching and, in Elixir's case, macros in a non-homoiconic language. And with ALL of these, it was speed relative to Ruby. ;)
Is a language even possible that has all the following features: purity enforcement, immutable data, pattern matching AND currying by default (Elixir/Erlang can't really do currying, sigh), macros, actual syntax ;) , monads/monoids, functional, compiles to JS, extremely cheap and completely isolated process spawning, arbitrary user-defined prefix/infix/postfix operators/functions, actor model style message passing (but possible to do in a deterministic way, since the messages themselves are side effects... unless all concurrent process actions are deterministic relative to each other... I hear haskell actually has a concurrency library that somehow features determinism), a not-braindead dependency scheme, a nice build tool (a la Mix)...
A nerd can dream.
This keyword is translated to a require <Module>
and <Module>.__using__(opts)
calls for a specified module:
http://elixir-lang.org/docs/stable/elixir/Kernel.html#use/2 https://github.com/elixir-lang/elixir/blob/v1.0.2/lib/elixir/lib/kernel.ex#L3256
What concerns me I'd prefer to not overuse this macros as it makes code harder to read. Ecto and Plug are good examples of macros overusing. But it's just my opinion on the topic.
&Task.async
"captures" the function, allowing you to pass the named function as an argument to Enum.map
.
&1
is notation for the first argument passed to the anonymous function.
See documentation here: http://elixir-lang.org/crash-course.html#partials-and-function-captures-in-elixir
Additionally, I would opt towards writing anonymous functions with named arguments, as it makes things a little easier to understand (in my opinion).
fn index -> calculate(index) end
First, I'm sorry this is happening to your daughter. That would test my "one door closes, another opens" theory of life, for sure.
I would like to plug a very promising project called Nerves. One of its deployment targets is the Raspberry Pi. It already connects to lots of different low-level hardware via interface boards and such, and has a number of interesting projects based on it. Lastly, it takes advantage of a relatively new language called Elixir, which is fantastic to work with (it compiles down to Erlang, but doesn't look like Erlang at all).
This looks like a much fancier version of something a built a week or two ago to cluster my nodes on AWS. I used ex_aws to query for EC2 instances with a particular tag, then Node.connect/1 to them.
Exactly. It is great to be able to parallelize easily (not unique to perl6, either), but using the results of parallel computation efficiently (hint -> it does not include waiting for all the computation to be complete and then continuing processing in a single thread), creating code paths with real-world complexity, ensuring reliability, being able to do this with multiple machines in a cluster (not just locally), ...
A rather more interesting approach is Elixir's new GenStage with the Flow API. http://elixir-lang.org/blog/2016/07/14/announcing-genstage/
Perhaps streams and function "repeatedly/1" may help get you started. You can take 50 and pipe that result to another (stream) function.
http://elixir-lang.org/docs/stable/elixir/Stream.html#repeatedly/1
It's strange because Elm is a reasonably elegant functional language approach to frontend.
PHP on the otherhand is best for mediocre procedural code.
Elm is leagues above PHP in terms of what languages should be, haha. Same with Clojure, Haskell.
By the way, if you're a fan of Elm/functional languages, have you tried out http://elixir-lang.org/ ? Elixir with http://www.phoenixframework.org/ is the best out-of-the box web language/framework duo I've had the pleasure of working with
On this note, something I've missed is a summary of methods implemented by a struct. Sometimes I know a method exists but don't know its name. I can't ctrl+f for it, so I have to scan the page until it jumps out at me.
Compare this to something like elixir's docs. They have a summary at the top of each type's page. Then on the left frame there are collapsible function listings.
Django is still a great choice for all kinds of stuff, including RESTful APIs.
One of the things I've been trying to branch out with is the Phoenix framework for the Elixir language, I like this one in particular because it has a nice high level, terse, and expressive coding style that I still find to be very readable. It reminds of Ruby in terms of what the language superficially looks like. Its built on top of the pretty incredible piece of tech that is the BEAM virtual machine for Erlang. This is one of the best systems for high availability, high concurrency applications that I know of.
When you are calculating the info_hash you can not rely on the data generated by re-encoding the info-dictionary. Not every bencoder sort the key/values the same when they encode dictionaries, so you need to get this info from the torrent file as it was encoded.
And I don't think there is any need to base16 encode the pieces data—but I could be wrong about that, I haven't gotten to the point where I verify pieces in my own implementation, but I have a feeling that this could be something specific for the Node-implementation and how buffers work in Node.js.
You could look into structs
for generating a nice data representation of the parsed torrent. http://elixir-lang.org/getting-started/structs.html
I hope that helps.
Mmm, I like it so far. I mean, error handling and maybe types are nice.
> [Debug builds] could be order of magnitude slower than release build and that is acceptable.
A worst case scenario I hope. And one that could be mitigated somehow. I feel like I should be able to keep my interactive application interactive while working on it.
I like integration between that were done with the preprocessor in C. I think it needs to be as strong as what you can do with C++ templates though. But less bullshit. It's insane to me to have to grapple with templates to get the compiler to execute code at compile and generate code. Give me Scheme's quote-unquote-quasiquote and I'd probably be pretty happy. Crystal, Nim and Elixir also all have macros of one form or another.
The above link does 404 for me, so here is the correct one: http://elixir-lang.org/getting-started/binaries-strings-and-char-lists.html
You'll find the reason for single quoted strings on that page:
> In practice, char lists are used mostly when interfacing with Erlang, in particular old libraries that do not accept binaries as arguments. You can convert a char list to a string and back by using the to_string/1
and to_char_list/1
functions [...]
So it's interoperability with Erlang libraries that makes this distinction important. The double quoted ones are needed for binary pattern matching, so Elixir needed both.
You are never too old to learn anything.
Getting that out of the way. I've been doing php stuff almost 17 years. I'm being a bit older then you.
I feel stuck, I feel trapped, I feel limited.
I've so much experienced but I'm hitting roofs with the technology. To a point I wish I wouldn't have invested such much into php but into diversity even more.
And of course I've worked with others techs. Devops, nodejs, elasticsearch, vagrant, C, ruby. The list goes on.
But I wish 20 years back I would have made different decisions (likely python, ruby or Java).
Not because I think these languages per se are necessarily better but I find that these are the languages where real innovation and influence happened (of course this is an oversimplification, there are many others).
But never did I feel php was leading in any way. Rather always trying to catch up with the others.
That's the real reason why I would suggest, if you want to get into web/programming for serious, for your future, look at things like e.g. http://elixir-lang.org/ or even NodeJs (though I sometimes feel the zenith was passed already), et al.
I think the biggest difference is that ElixirSips started when Elixir was still pre-1.0, so some of the introductory videos are now outdated and old.
LearnElixir.tv is more expensive and has less content. IMO you're better off doing the getting started guide on elixir-lang.org (which has more info than LearnElixir.tv and is free) and then switching over to ElixirSips which has way more diversity beyond just the language itself. For $9 theres over 200 videos, thats a good deal!
This is (IMHO) the best one: Elixir In Action. But everything in this page in very good. :)
EDIT: haven't read the second bit the first time, sorry. I'll try to respond. No, channels are NOT the solution to safe concurrency, neither is in general functional programming. Channels in Go implements a messaging pattern that you could use to write safe code, but this does not protect you from deadlock¹ etc. And functional programming is built on value passing instead of reference passing (you do not pass the variable, you pass only it's value), but it does not protect you from side effect as a whole. In fact, Erlang solve this problem with the OTP and his internal scheduler. If you adhere to the OTP standards, your are quite good to go.
¹ go has tools for detecting race conditions.
You make some good points but for example in Elixir I could type "mix new project_name" and it would bang out all the relevant files. Host would have to be able to serve Erlang files though, you're correct that everyone can serve PHP and deploying PHP is stupid-easy. (Perhaps emphasis on "stupid" ;) ) Deploying Erlang/Elixir is... sadly... less than trivial. (Maybe I will work on that.)
Techguy here (always into the latest stuff, now it's Elixir) who got comfortably monied on Bitcoins after my girlfriend made me watch "The Good Wife" episode featuring them and I became obsessed. Sold most of them at $900. I don't deserve this car. But you know the type I'm talking about. Anyway he asked, so I had to resort to stereotypes
Yes. Variables in a case statement "head clauses" are not bound to the upper "context", but body clauses are. You can read about this in the docs here under "Variables Handling":
http://elixir-lang.org/docs/stable/elixir/Kernel.SpecialForms.html#case/2
Note that it should be more idiomatic to assign to the result of case rather than within the body of the function.
One of the big things I love about Elixir/Erlang. To act dangerously, you just... live dangerously and embrace failure, because an OTP supervisor process will restart you in a microsecond after logging the error if there is a problem. (Seriously, you can start over a million new processes in less than a second on any modern hardware on the BEAM VM.) You account for all the states you can conceive of (or care about, like the "happy paths" through the code), and any unexpected ones are handled by that mechanism.
This is a smart design as failure is bound to happen anyway either from unexpected I/O state, unexpected internal state, or cosmic-ray bit-flipping. (The first two are where NULL problems typically hit.)
You're misunderstanding what require
does. It does not transfer bring functions and macros into the current namespace, it instead allows you to call macros from other modules in the namespace.
http://elixir-lang.org/getting-started/alias-require-and-import.html#require
What you are describing is an an unqualified import
, which I agree, is less than ideal. However, you can just import the needed functions quite happily, like so:
import List, only: [duplicate: 2] x = duplicate(:ok, 10)
Or, better yet, use alias
, which gives you a shorthand for qualifying modules, rather than polluting the namespace at all.
alias My.Long.Module.Name x = Name.foo()
alias My.Long.Module.Name, as: N x = N.foo()
I just started reading through your article, and saw this:
> Originally I was hoping to be able to pass in the already defined arithmetic functions in Elixir such as Kernal.+/2 but I was unsuccessful in passing the function without it being evaluated.
What you want is the Capture operator which looks like:
iex(1)> fun = &Kernel.+/2 &:erlang.+/2 iex(2)> fun.(2, 2) 4
So to use any function with your Elisper.eval/1
function, you simply have to it like so:
iex(1)> Elisper.eval [&Kernel.+/2, 2, 2] 4
or since Kernel is imported by default, this would also work:
iex(1)> Elisper.eval [&+/2, 2, 2] 4
That would negate the need for your native_ops
map and greatly expands the support for operations in your implementation. An actual parser would just need to map keywords to built-in functions with the proper arity.
The elixir tutorial touches on this sort of thing starting here if you want a look at it from the ground up. Seems to me like a better place to start than diving straight into an existing library, but that's just my perspective.
If you want a 'ruby like' language with concurrency and speed you can try with elixir (built on top of erlang vm)
An a rails like framework http://www.phoenixframework.org/
Another suggestion I'd make is learning another programming language. Especially one with a different focus. My personal favourite at the moment would be a functional language like Elixir (http://elixir-lang.org). Even if you never use the other language professionally it'll give you a different way of approaching problems.
Have you checked out Elixir?
It's a language with Ruby like syntax, Lisp macros, and an operator like the Unix pipe operator, which you talk about in the "why" section.
"Hello, world"
|> String.split(" ")
|> Enum.join(" ")
It targets the Erlang VM (and is very similar to Erlang), it seems to do a lot of what you seem to be after here, and it's a lot of fun. Check it out. :)
The article talks about how Enum.reduce has worked, but Enumerable.reduce is a different beast which supports halting and suspending to a sort of continuation function.
http://elixir-lang.org/blog/2013/12/11/elixir-s-new-continuable-enumerators/
As others have pointed out, a functional language would be good. You will learn a very different way of coding and maybe be surprised how effective a functional language can be for specific problems.
I recommend looking into Racket and or Elixir. Elixir shows great promise to become big in web development and Racket offers a great all around package and awesome tutorials/books to learn functional programming.
There are certainly other good choices. Good luck!
For what it's worth, I made a Ruby monkeypatch manager gem which basically allows you to write a monkeypatch in such a way that if an assertion (that the patch is still necessary) doesn't pass, at runtime, the patch won't be applied and you get a console message.
The tricky bit is, of course, writing the test case to assert the patch is still necessary.
This is meant mostly for self-expiring bugfix patches and not for feature-adds. Although you could for example ensure that your feature-add doesn't namespace-clobber some same-named feature added by another gem.
I was forced to write this after looking at the old repo I was responsible for and seeing tons of unchecked monkeypatches, still running, that fixed bugs that have long since been patched up, leading of course to unpredictable behavior/bugs.
It was these kinds of Ruby shenanigans which drove me to Elixir, by the way, which already happens to implement this Transproc idea (out of the box) as a simple pipe operator: |> (see this blog post for a demo)
Use whatever tool/framework you like. Fuck popularity.
I liked Ruby for over 10 years (back when it was below everyone's radar... there was just "something about it"). Now I desperately want to find work in Elixir.
One thing you could try is a back end language with a paradigm that's not imperative or object-oriented like ones you know, PHP and JavaScript. Two I could safely recommend are Elixir or Clojure. Since HTTP should be stateless, functional languages lend themselves well to solving those issue. Being able to reason about a problem in more than one paradigm will help you as a problem solver by giving you a new tool to work with.
Along that vein, and since you're looking into React, you should really check out Immutable, an immutable collections JavaScript library also out of the minds at Facebook.
FYI, I was confused/annoyed by the Regex library, until I found that the String library has many corresponding functions with string as the first parameter.
http://elixir-lang.org/docs/stable/elixir/String.html#replace/4 http://elixir-lang.org/docs/stable/elixir/String.html#match?/2 Etc...
EDIT: Should have read the rest of the thread! So redundant!
People from Ruby can actually read Elixir.
#sarcasm
But also... Macros! It is rare to have "true" macros available in a language that is not homoiconic.
"Elixir is a dynamic, functional language designed for building scalable and maintainable applications.
Elixir leverages the Erlang VM, known for running low-latency, distributed and fault-tolerant systems, while also being successfully used in web development and the embedded software domain."
It's possible to specify the timeout on assert_receive http://elixir-lang.org/docs/stable/ex_unit/ExUnit.Assertions.html#assert_receive/3
You can also just unit test the handle_call, handle_cast functions and have no timeouts at all. Just test the input/output according to the specified behaviour.
On integration tests for async execution you will find timeouts and sleeps a common approach out there.
P.S.: there's a typo "aysnchronously"
I really like the Phoenix framework in Elixir. I'm not sure that there's much that can beat the BEAM in terms of scalability. In my experience functional programming leads to really maintainable code. The ecosystem is great. Elixir's macros and the awesome Hex package manager makes it really easy to extend the language. The one of your points that it really fails on is that it's so new that there aren't many jobs yet.
If you want to try something different, checkout erlang / elixir (elixir is a new language built on the erlang VM). Some of the classic erlang / OTP books have you write a chat program over the course of the book.
Note of course that erlang and elixir are functional programming languages and will feel pretty foreign at first, but the differences (immutable data, recursion) make distributed programming very easy.
Checkout: http://elixir-lang.org/ https://github.com/phoenixframework/phoenix # A web framework written in elixir that has great web sockets support, making a web chat framework very easy.
In fact, someone recently made a blog on how to do so, I highly recommend at least giving it a read: http://chrismccord.com/blog/2014/05/06/how-to-build-an-elixir-chat-app-with-phoenix/
Good luck!
For me I used http://exercism.io/ for exercises.
I also read the getting started: http://elixir-lang.org/getting_started/1.html
And referenced the docs (and google) when needed. http://elixir-lang.org/docs.html
The structures you have said are not disjoint sets. As basic collections Elixir has lists (linked lists), tuples (contiguous in memory) and maps (associative data structures).
Records are tuples and today they exist in Elixir just for compatibility with Erlang. Records in Elixir are just macros for manipulating tuples and they are usually avoided unless you need to interact with an Erlang library that relies on them. Records are compile time only.
Structs are maps with a key named __struct__
that points to a module. Structs also allows you to provide default field values and give you some compile time guarantees (think of them to be named maps).
Keyword lists are a list of tuples: [foo: 1]
is literally the same as [{:foo, 1}]
.
Dict is just an "interface". It just defines an interface that you can use maps, keyword lists, as well as a HashDict, or any other associative data-structure you are able to implement.
This chapter in the getting started guide explains exactly when each should be used and why there are three main options right now: http://elixir-lang.org/getting_started/7.html. We hope to get down to two options once maps are improved to support large values.
Real-time systems can't always afford downtime, and there aren't exactly a lot of options. Unless you use a good language that supports live code reloading like Elixir, then it's less painful.
Elixir is a functional programming language. If you don't know anything about functional programming, I don't know how much of an advantage that is. Here's a primer for the uninitiated.
Elixir also has excellent support for fault-tolerant concurrency. Basically, it lets you write applications with many threads where one thread crashing or having a critical error does not crash the whole program; they are each isolated.
Elixir and Phoenix are also generally capable for writing web applications; they have a number of useful modern features. But I think most of them are also present in languages like Ruby, Python et al. so the two points above are the main advantages.
What do you mean with "programs"? Applications that run on terminal? Applications that user interacts directly? Any code that encapsulate a state?
It is important to define that, since elixir is fp and the examples you gave are imperative and oop. Most of the things you would expect from a language like java, python, ruby, can't be expected from elixir/erlang. First of all creating an elixir application are related directly with OTP, since an application is an abstraction inside the OTP principles. To create an out of the box application in a fast and direct manner, I can suggest you this "how i start" written by José Valim: http://howistart.org/posts/elixir/1
The Getting Started guide is really good, and if you do the Mix and OTP section will help to understand more: http://elixir-lang.org/getting-started/mix-otp/introduction-to-mix.html
Lately, when I look at various tutorials (e.g., http://elixir-lang.org/getting-started/introduction.html for Elixir), it tends to focus a lot on the various features of the language, but not that much on how to solve a problem in the language. I almost feel like there should be two tutorials. One covers the language and is meant as a reference. The other works on problems which can be structured around using features of the language.
I suspect that's what the labs are for. Quite often, the online tutorials don't have an accompanying lab. So you might have a good approach.
Toxic can mean a variety of things. Unhelpful, harsh to newcomers, mean spirited, snide remarks, many things can contribute to making something or a group of people "Toxic".
Better Syntax is kind of just all over the place tbh...I'd have to point you towards http://elixir-lang.org/getting-started/introduction.html :/
At a glance places of interest seem to be Sigils, Tasks, Agents, and Metaprogramming.
Since you know python you could enjoy other paradigms with also python libraries. There are a few python variants: https://github.com/vindarel/languages-that-compile-to-python
Also I wouldn't learn C, but a higher level language like Elixir http://elixir-lang.org/docs.html which is similar to Ruby but has many new concepts.
You will very probably need to know javascript later or sooner, but here again you have plenty of choices: a functional and terse variant (livescript, awesome http://livescript.net/), a haskell-like variant, etc
Add all of the Flow operators, especially |>
, to Prelude.
Elm has this, and it makes code so much easier to read!
(Incidentally, Elixir also has the |>
operator, and some hail it as one of the greatest features of Elixir.)
Yes, all your modules that are in the main project directory or external dependencies as specified in your mix.exs
file will be imported and made available throughout your project. You can find out more about how to customize paths (for builds, compilation, load paths, etc.) here.
I threw this together, it works with Maps. Includes a couple assert/refute tests.
Once you convert the json to a map, this should theoretically work for determining if any nested value exists in the nested map.
Will leave as an exercise for reader to make doable for any key/value enumerable. ;)
Quoting "Getting started"
> The reason we can compare different data types is pragmatism. Sorting algorithms don’t need to worry about different data types in order to sort. The overall sorting order is defined below: > > number < atom < reference < functions < port < pid < tuple < maps < list < bitstring > > You don’t actually need to memorize this ordering, but it is important just to know an order exists.
It's just Terminal.app with a few tmux panes...the left side being Neovim with code for a game I'm writing, the upper right is debugging output in Elixir's interactive environment, and the lower right is just a Fish shell session.
One way of doing this is to start a supervised task like in the getting started guide: http://elixir-lang.org/getting-started/mix-otp/task-and-gen-tcp.html#task-supervisor
That way your genserver is basically just responsible for delegating work out, you could even have the response sent directly back to the client.
def add_message(pid, message) do # Call your genserver to get a reference to listen for ref = GenServer.call(pid, {:add_message, self, message}) # Have client wait for response receive do {^ref, data} -> data end end
Your example is already making assumptions that strings are always 'strings of characters'. What if my language is like Elixir, where strings are represented in binary UTF-8?
Which is funny, because the language that Elixir is derived from (and still runs on its VM), Erlang, represents its strings as linked lists.
While "you", the language designer aren't building a language "from your gut", but building one for purpose (or at least trying to).
The authoritative source in this case, would be years of design experience from other language implementers. Why do most popular languages fail when you operate out of bounds? Are there other languages that do something different?
Were I you, I would take this as a learning opportunity about the complexities of language implementation, rather than complaining people "aren't playing nice and just answering the question."
No need for apologies! :) Of course function reference is a more correct description than lambda function in a stricter sense.
But if we were to define it precisely, is it really a reference? Sure, it's a good intuition for people familiar with similar concepts from other languages but I have no idea how &f/n
is implemented inside the compiler (will have to dig into the source code to check). The documentation calls it simply <u>function capturing</u>.
Regarding learning and terms, I think people usually get confused with lots of similar terms but learn the difference with experience.
First thing, your spacing is way off. Idiomatic Elixir uses 2 spaces and no tabs, check your editor is setup right.
Second, it seems what you want from your PubIpMon.CLI module is a mix task. Read about mix tasks here.
Also, I suggest you keep your functions which cause side effects (in this case the ones that do IO.puts) to a minimum so that those functions are easier to test.
Try looking at using the new with
keyword in Elixir 1.2 if you're brave and remove all the IO.puts from all functions except PubIpMon.Comparator.compare/2
.
You might find it best to start by taking a look through the official Getting Started documentation (http://elixir-lang.org/getting-started/introduction.html), if you haven't already. It's really good; especially once you get to the 'Mix and OTP' section.
I have started learning Elixir a few weeks back and honestly it feels a lot like what node wants to be, but is not. The concept is an entirely different one, though, so if you only have a node background and no Ruby experience, it might take a while to get used to.
The language is still young, so the community and eco system are still small and we'll have to see how that turns out in the long run. But the technology itself feels incredibly mature and well thought out and the people that have gathered around it are incredibly enthusiastic and helpful in getting you started.
The paragraph that sold the language to me was this particular piece from the (exceptionally well written) "Getting Started" section of the official site:
> In Elixir, we avoid using try/rescue because we don’t use errors for control flow. We take errors literally: they are reserved to unexpected and/or exceptional situations. In case you actually need flow control constructs, throws should be used. That’s what we are going to see next.
I think this is the only bolded text in the whole 21 chapter Getting Started section. That made me so happy.
If you're sick of node, that's what I would recommend looking into.
To add to these great answers, at the point you do need to learn the Erlang syntax (which will happen sooner or later), a good place to start would be on this page.
In the function head
is a single element of a character list or binary. For these + is defined. In iex you are trying to add on a binary (the whole string). Try something like <<110+n>>
or [110+n]
and you should see the expected output.
Also have a look here.
Edit: You can even do it like this to be more epxressive about the "n": <<?n+n>>
.
He should have said "editors." By "tools" I thought he meant "tooling" such as Mix, Dialyzer and :observer.start().
I guess I'm from the "if you need more than a simple syntax highlighting text editor and a command line, something is wrong" school.
I think by 'umbrella' you are talking about an 'application' as it is understood in the Elixir/Erlang world. When an OTP application is used in a project, it launches an Application process which supervises several other processes which do the actual work. These supervisor trees are essential to the most important parts of Elixir and while it can take some time and experience to grok them, they are the primary reason to use the language and VM.
ExIrc seems to be set up like a fairly compliant OTP application. What you need to do is set up separate clients and event handlers for your 'listener' and 'whisperer' connections and then have the listener pass messages to the whisperer. How to do this is a bit involved, but a good place to start is the documentation on GenServer; pay particular attention to the bit about Client / Server APIs.
If you really want to get moving on this sort of programming, I am unfamiliar with any Elixir-centric documents which are of an appropriate level. There is, however, the free and very good learn you some Erlang for great good. You have to bend your brain a tiny bit around the Erlang syntax, but it will walk you through the concurrency model and how OTP processes work.
I am, this exists though. It's just a matter of replacing:
|> :math.sqrt
with:
|> (fn x -> Float.round(:math.sqrt(x), 4) end).()
So, when the value gets piped it, it's invoked, the square root is taken and the result is rounded to the fourth decimal place. I find pipelining amazing, it's a really clear way to compose functions.
EDIT:
Or, you could even extend the pipeline:
|> :math.sqrt |> Float.round(4)
First of all, workplaces have cultures, cultures select for similar worldviews. If their worldview offends you, then you just won't end up working there, and others will. Simple.
My work criteria are simple: Forget hard-to-prove rules. Just don't be an asshole. Want to know why you can't get any more complicated than this? Because all other constructions/correlations assume something negative. For example:
"CIS white men often have more spare time or chose to pursue building up an impressive portfolio of code rather than women or minorities who have to deal with things like raising children or instiutionalised racism."
The negative assumption here is that NO women or minorities are successful enough to have enough free time to polish out a Github portfolio, and that if some WERE so successful, that it is acceptable to false-positive them right out of the eligible worker pool... Or that applying this rule on a broad scale is worth the cost of disenfranchising successful (and arguably highly skilled) female or minority developers.
Other negative assumptions include: ALL women are dealing with raising children ALL of the time, and ALL minorities are dealing with racism which is costing them time ALL of the time. (Is that true?)
Disclaimer: I have a bias here. I was very successful last year, I'm (sigh) a white male (the term "CIS" is already way too loaded for me), and switched to part time contracting and am spending a bit of time building out a github portfolio in a new language precisely because there IS NOT a ton of work available in it yet, and I need to demonstrate something (and I'm hoping that "using my free time to exercise my ability in this new language and also have some fun" is that something).