HN user

strmpnk

1,140 karma
Posts27
Comments376
View on HN
github.com 7y ago

TLA+ 1.6.0 Released

strmpnk
3pts0
www.stanleyparable.com 7y ago

The Stanley Parable

strmpnk
4pts0
www.eecs.harvard.edu 7y ago

Why Systolic Architectures? (1982) [pdf]

strmpnk
82pts5
poignant.guide 7y ago

Dwemthy's Array

strmpnk
2pts0
nerdlypleasures.blogspot.com 7y ago

Exciting Developments for NES ROMs

strmpnk
2pts0
www.youtube.com 7y ago

Super Mario Land 2 – Memory Exploration

strmpnk
1pts0
www.youtube.com 8y ago

Symbolic Leisure

strmpnk
1pts1
github.com 8y ago

Simple X hotkey daemon

strmpnk
1pts1
kakoune.org 8y ago

The quest for a better code editor

strmpnk
4pts0
blog.wallaroolabs.com 8y ago

The Snake and the Horse: How Wallaroo's Python API Works with Pony

strmpnk
9pts0
blog.wallaroolabs.com 8y ago

Exploring the GitHub Archive

strmpnk
11pts1
www.anandtech.com 8y ago

A Timely Discovery: Examining Our AMD 2nd Gen Ryzen Results

strmpnk
1pts0
alephone.lhowon.org 8y ago

Aleph One – Marathon Open Source

strmpnk
1pts0
github.com 8y ago

Dash compatible docset for the Pony Language

strmpnk
1pts0
www.mac4n6.com 8y ago

Logs in High Sierra Show Plaintext Password for APFS Encrypted External Volumes

strmpnk
4pts1
www.youtube.com 8y ago

The Hitchhiker's Guide to the Unexpected [video]

strmpnk
1pts0
github.com 8y ago

Universal Ctags

strmpnk
2pts0
blog.couchdb.org 8y ago

CouchDB Remote Privilege and Code Execution

strmpnk
1pts0
arstechnica.com 8y ago

A brief history of quantum alternatives

strmpnk
8pts0
blogs.janestreet.com 10y ago

Self Adjusting DOM

strmpnk
5pts1
blogs.janestreet.com 10y ago

Incrementality and the web

strmpnk
54pts11
www.lexaloffle.com 10y ago

PICO-8 v0.1.2 Released

strmpnk
2pts0
pico8fanzine.bigcartel.com 10y ago

PICO-8 Fanzine #2

strmpnk
2pts1
medium.com 12y ago

The Erlang Shell

strmpnk
127pts60
generalassemb.ly 14y ago

General Assembly Launches Hybrid Education

strmpnk
5pts1
www.ft.com 14y ago

General Assembly opens in London

strmpnk
1pts0
backstage.soundcloud.com 15y ago

MySQL for Statistics

strmpnk
5pts0

I had a diplomatic passport for many years as a kid. It was definitely handy in our case as cops were quite corrupt where we were living and would try to con us out of money all the time. I don't know how far it'd go in court or under a serious warrant but in practice they always left us alone once we showed our passports.

I wouldn’t call twice as fast neck and neck (others seem to show that the old interpreter is neck and neck) but the primitive JIT is clearly pulling ahead here.

I was curious to see what my JIT build looked like for me so I ran the following: https://gist.github.com/cararemixed/c232b888b9dbdaeb67967f35...

This shows a significantly different story between the two with at least similar code. Note I am not trying to optimize for the fastest factorial here as both can be made much quicker but roughly equivalent code seems to tell a different story for me.

(NOTE: I put the code in a module as iex interpreted expressions on the top level are always slower than compiled modules, even when pasting them into iex. Doing the same for Ruby didn't show any difference for me.)

This is sort of what Pony did with its ORCA based GC. It has some tricky edge cases to optimize in practice but it can be made to work especially well if data is immutable.

The analog for that would be shared literals which are not copied (super important for small map overhead reduction if the constructor initialized a fix set of keys like elixir structs as the key index is shared). The persistent_term module allows any value to be registered as such at runtime and avoids a lot of caveats that came with mochi_global and the like. While they aren’t ref counted it can definitely help cut down on copying in my experience.

I’d suppose some of it relates to sites with heavy ads. Safari with no extensions will likely require more resources which makes the comparison a little skewed vs Safari with some ad blocker support added via extensions.

It looks like their test includes plenty of ad heavy sites like news articles which seems to confirm that the results are cherry picked.

I’m trans and agree with this, though I offer another reason to avoid making it compulsory.

Before I came out I felt very awkward with regards to my own pronoun display. I wasn’t ready on one hand and on the other I felt terrible seeing other pronouns even if it was attached to my deadname only.

I’d encourage people to do it if they’re comfortable with it on a personal level as it can be a very personal thing. I also want to thank all of those who do add it. It’s a big deal for many of us and can make a real difference in exchange for very little effort.

I looks like it’s written in Rust which isn’t super special but would be far easier to embed as a library in other languages compared to Go in OPA’s case. Polar also seems like a nicer policy language (strong Prolog vibes) though this is subjective as I’ve not done a deep comparison yet.

This is true, but the difficulty of making a general purpose FPGA fabric manipulate generic bitstream descriptions in an undetectable way is much harder than putting hidden backdoors in well defined ISAs. What amount of hardware validation is reasonable?

It depends on what you'd like to accomplish, but given that powerful FPGAs are now more affordable and plenty of great FPGA friendly libraries are emerging which work with open source tools, the barrier for Soft-CPU implementations has lowered significantly. This sort of project looks great for cases where trusting blackbox chips was questionable.

The other plus of text replacement is synchronization. I have a bunch of LaTeX style symbol names mapped on my Mac but they work just as well on my phone. I’m typing this on a phone and \Omega is automatically replaced with Ω or a favorite of mine \shrug becomes ¯\_(ツ)_/¯.

I also spend time on Windows and nothing seems to come close to this convenient (win-. has a few useful things like the character picker panel in macOS but to get more, tools like autohotkey feel really cumbersome).

I don't think this is the issue the prior article mentions about the bit string syntax. It's a notational problem paired with the combination of bit numbering and byte endianness.

The article makes it look trivial but if you note the ASCII diagram starts by labeling each byte-row with 7 not 0. Without some way to switch bit numbering (kind of like bit endianness) of the entire expression, we can't make something that looks like continuous bits in one view look continuous in the other.

A reduced example:

     7   6   5   4   3   2   1   0
   ------------------------+-------+
 0   5         X         0 |   Y   |
   ------------------------+-------+
 1  13            X              6
Here we can't say <<Y:2/little, X:14/little>> (Y is bits [0,1], X is bits [2,15]) because we need to read <<X1:6/little, Y:2/little, X2:8/little>> (X1 is bits [0,5], Y is bits [6,7], X2 is bits [8,15]).

The interpretation of the contents of those bits will be done in "little endian order" (odd term since endianness is a byte order not bit numbering concern) as the expression says but because Erlang or similar syntax has no knowledge of the bit numbering we have in this diagram, it can't automatically assume that the first bit is numbered 7 not 0.

Laying the bytes out on a line makes the notational problem more obvious:

     7   6   5   4   3   2   1   0 |  15  14  13  12  11  10  9   8
   ------------------------+-------+---------------------------------
     5         X1        0 |   Y   | 13            X2             6
   ------------------------+-------+---------------------------------
Even if we know that we interpret each number with a given endianness, the bit stream numbering here needs to be expressed separately at the top level. Generally, this is why serialized protocols prefer to start bit numbering at 0 like the written in the IPv4 header example.

It does apply to Elixir. It will help all around performance but more so it does this on a per-instruction level by reducing dispatch cost in that the interpreter pays (as well as managing to specialize things a little better than what the fixed instruction tables can express).

To get an idea of the instruction stream of the BEAM (not the same as .beam asm), you can use the erts_debug module:

    iex> :erts_debug.df(String)
This will dump a BEAM machine instruction stream to a file named Elixir.String.dis in your current working directory. You'll see things like:
    000000001B81AFB0: i_func_info_IaaI 0 `'Elixir.String'` `at` 2 
    000000001B81AFD8: is_integer_fx f(000000001B81AFB0) x(1) 
    000000001B81AFE8: is_ge_literal_fxc f(000000001B81B008) x(1) `0` 
    000000001B81B000: i_call_only_f loc(`'Elixir.String'`:`do_at`/2) 
    000000001B81B008: allocate_tt 2 2 
    000000001B81B010: move_window2_xxy x(1) x(0) y(0) 
    000000001B81B018: i_call_f loc(`'Elixir.String'`:`length`/1) 
    000000001B81B020: i_plus_xyjd x(0) y(0) j(0) x(0) 
    000000001B81B030: is_ge_literal_fxc f(000000001B81B060) x(0) `0` 
    000000001B81B048: move_shift_yxx y(1) x(0) x(1) 
    000000001B81B050: i_call_last_fQ loc(`'Elixir.String'`:`do_at`/2) 2 
    000000001B81B060: move_deallocate_return_cQ `nil` 2
Each of those instructions are what the .beam file loader currently generates. With the JIT, these will be replaced by machine code.

I remember that year. I was giving a talk at EF during the same time slot but the schedule originally had me in the large room and they had a much smaller one.

When the news of the acquisition hit, everyone wanted to see the WhatsApp talk. The organizers knew this so we swapped rooms. So, I started my talk by asking if anyone in the room was here for the WhatsApp talk and told them they could quietly leave and I wouldn't mind and a bunch of people got up.

Heheh. I don't blame them. I didn't really like my talk and Rick Reed is very good at what he does and the talk is no exception.

This is far from the first JIT effort for BEAM. I'm sure the authors have rolled many years of learnings and experience into this one. Still, you make a good point, it will need a lot of testing by the community before I'd trust it in production.

I believe the distribution layer built on top of ETS and DETS you’re trying to name is mnesia. It supports distribution and allows a variety of interesting topologies. It’s not the only distributed data store available on the BEAM but it’s well tested, mature, and comes as part of the OTP libraries.

I can also mirror this general guideline. I've run 250+ node erlang clusters just fine in the past. There were some caveats to how some built-in OTP libraries behaved but they were easy to replace or workaround in the past.

That was many years ago as well. The distributed erlang story has improved with more recent releases (better performance on remote monitors for example) which might push the number a little higher than 300 if you are careful. Keep in mind the default style of clustering is fully connected so there is some danger in managing that many network connections (quadratically scaling for each node added) during network partitions which can be a problem if you're not tuning things like TCP's TIME_WAIT for local networking conditions.

Even better, these days there are great libraries like partisan (https://github.com/lasp-lang/partisan) which can scale to much larger cluster sizes and can be dropped in for most distributed erlang uses cases w/o much effort.

OTP 23 6 years ago

Much of the erl_interface functionality prefixed with erl_ names has been deprecated since OTP 22 and has been removed. The API has shifted to newer ei_ prefixed functions. I believe there are some new deprecations in place as well which you can find the longer form release notes.

erl_interface itself is not going away but it is evolving with the BEAM VM. Deprecation warnings should be checked when compiling code on each major release to avoid surprises as features are usually deprecated for one release and then removed in the next release each year. The erl_interface documentation should be up to date with regards to new APIs and might be worth browsing again to get an idea of the what changes look like.

It’s technically the receive primitive doing this using the after clause. The addition of unique references and selective receive then allows “call” style interactions to built (like gen_server).

Likewise, links and monitors are used for lifetime concerns instead of reference counting actors like Pony or using a global tracing collector. This has some advantages and disadvantages but for the most part I personally find it far more practical than other models which are more like the classic actor model.

I see. Fair enough. It's definitely something I know can work but like most things it does take work and sometimes it's not worth the trade in effort for the capabilities one might gain otherwise.

Badfun errors are a great example of something tricky if you're not used to thinking about how the compiler translates these to private functions via lambda lifting. It's the same reason funs are not something you should rush to pass around over a disterl cluster. Recursive functions which keep fun's around in a loop also become a problem if they're long lived.

I usually point out that first class modules or MFA tuples are more idiomatic in Erlang than opaque first class functions as values but we're off into the weeds here. It's a good example of where effort and gotchas become a barrier for many.

That’s a bit misleading. Many of their patches were needed and had been contributed upstream by the time Phoenix was being tested as such. Still, this is a great benefit of sharing the ecosystem as such as everyone gets to benefit from this work.

I’d not consider relup and module loading the same feature. It is rare to see relup (though I have used it, it’s tricky to make work) but hot code loading of modules was something we used extensively both during development but also in production to test out patches for problems. It was super easy to use and never a big problem.

Keep in mind that we rolled out the patch incrementally to one or two machines and then to more. If it looked good we’d roll it out to the rest of the cluster. From there we’d make note of the result and get the change ported into a proper release.

Each time I hear stories that both clustering and hot upgrades, module loading, etc are hard or rarely used I wonder if the person is just repeating someone else’s rumor. They’re great features and work fine if you do a little homework (just like learning anything, don’t treat it like magic).

This was from my time at Cloudant/IBM, though its far from the only case I’ve seen. We ran over 1000 machines this way with some clusters growing to more than 200 nodes using distributed Erlang (something I keep hearing is hard or impossible, it’s not).

There is ongoing to work to allow support for counted looping (including a working patchset that is under review) but in general it's true that an eBPF program does not allow a given segment of code to have multiple entry points (a generalization of the prior rule that jumps may only jump forward in the instruction stream).

AFAICT lanes are not shared but there are chipsets which can break lanes out into other sets of lanes which are then routed back onto the original set of lanes. So if your CPU has 16 lanes you can hang a chip off of it which then provides more lanes which are then signaled back to the CPU over some subset of those lanes.

It’s not clear if the lanes themselves can be multiplexed with packets from many devices but they can change the number of assigned lanes after initialization so a clever chipset could probably dynamically allocate lanes as used.

Pony 0.29 7 years ago

It's definitely true, though likewise, it's expensive to use locks in such places too. The main idea with Pony's runtime is that contending for an actors attention will certainly incur costs but independent pairs of actors should not, even during GC.

I also glossed over the I/O system and back pressure support which make the above discussion a bit more nuanced but my goal was to lay down some form of intuition around thinking in terms of progress in a system as a guarantee of the concurrency model.

Empirically speaking, there are real limits to what hardware will hide and plenty of room for leveraging knowledge of the system as a whole (esp. the memory model) rather than sticking to one set of abstractions. Pony is no exception here, though the co-design of various features might make that less necessary than it might be in other systems with similar properties as it matures.

Thanks for this tip. I find myself a little more reluctant to rely on environment variables for this sort of thing but it'd be fair to say the same about filesystem state.

My only problem with this solution is that it changes the mix configuration itself (which is version controlled) which is fine if others are in need of similar overrides when working on the project. For one-off/local things, it can be a bit heavy for temporary overrides.

Still, it's a fair trade-off since it's a lot easier to code up logic like this with mix compared to rebar3.

The original claim is just as pointless. The implication that Elixir fixes Erlang's syntax is so commonly repeated without much discussion that it has many folks dismissing the entire language before they learn it.

I think both languages have issues with Syntax but in the cleaner department, I am baffled at the insistence that Erlang is hard. Inconvenient, maybe but most of the features in Erlang are so primitive that there is little to no ambiguity of what something can mean.

Verbosity strikes both (records and binaries in Erlang vs the sigil and keyword heavy Elixir code) and certainly some folks prefer rebinding variables and colon syntax on atoms but it's certainly not without real trade-offs in common idioms (tagged tuples, special casing required for atoms like true, false, nil, interop with Erlang becomes uglier, etc).

Thanks for the correction and clarification. The early parts of the docs didn’t make this distinction clear so I assumed the WASM half was required.