> Concurrency is hard and if you want M:N thread multiplexing (i.e. WEB SCALE CODE, where application threads aren’t pinned to pthreads) your options today are precisely Erlang, Go, .NET, and Perl 6. Putting aside the "web scale" jokes ( http://www.mongodb-is-web-scale.com/ ), this statement is still absurd. Every major language, or at least the ones that matter for backend development, has support for thread multipl…
Nonsense: Solaris has had that thread multiplexing for over 15 years, for one counterexample.
Why I’m Learning Perl 6
341–350 of 380 posts
Re: Why I’m Learning Perl 6
#342Perl 6 carries 2 pieces of baggage from its predecessor - prefixing variables with "my" to create lexical scope and the obligatory "use v6;" at the top of every script. Why can't an advanced language like Perl 6 scope variables without littering "my" everywhere? You don't see it in any other mainstream language I can think of.
I strongly disagree: From a languge design perspective, block-level lexical scoping with explicit declarations is superior to all alternatives I'm aware of.
Re: Why I’m Learning Perl 6
#343Earlier quoted context omitted.
Very true. Node does this too, in the sense that all node libraries are async/callback aware or have async/callback versions of those. I much prefer the go/erlang version of this. Playing the "what color is your function" game or "will it block" is no fun.
> Playing the "what color is your function" game or "will it block" is no fun. This was quite painful with.js Node 1-2yrs back when Promises and coroutines started picking up steam [such as https://github.com/tj/co ]. It was always a shot in the dark. Has this situation changed now? (basically is the stdlib all async friendly now?)
Re: Why I’m Learning Perl 6
#344Earlier quoted context omitted.
You deferred updates to the owner via scheduler, with high prio, and continue. parrot threads are lock free but not wait free. The NQP compiler needed to know about threaded writes and schedule the update, with a semaphore, while the other threads continue. What MoarVM got better was everything else. The GC, the calling convention, the OO (6model), the jit. I was on my way to fix all the parrot damage done from the p…
I fail to see how using a semaphore to schedule work in another thread is "lock-free."
Google for lock-free vs wait-free
Re: Why I’m Learning Perl 6
#345Earlier quoted context omitted.
> 10 different ways of doing the same thing Mostly an urban myth. Where it isn't, at least 8 of those ways are actually important. Exercise: write a python program that prints Python's quoting documentation, without external files, without editing the documentation. Spoiler alert: it's impossible.
So, how exactly these different ways of getting sub arguments are useful? sub add1 { my ($arg1, $arg2) = @_; $arg1 + $arg2; } sub add2 { my $arg1 = shift; # possibly two screens of dense code here, then my $arg2 = shift; $arg1 + $arg2; } sub add3 { $_[0] + $_[1] } # There may be some other ways to extract arguments # that I am not aware of. # It's possible to combine any of the methods! And this is just argument acce…
The first example uses the explicitly named default array @_. This is a common pattern, and easy to read.
The second one omits the "default". Note that whilst it is possible to write some dense code between the $arg1 and $arg2, it won't work as expected if the dense code bit has array access - ie., the default array can change in the code.
The third example uses the typical sigils for accessing individual elements within an array (default or otherwise).
I wish the core language had saner defaults, but over time, I've seen some reasonable uses for the different styles:
1. General subs, the same as you example
2. shift removes the first element of the array and returns it. This can make the code more readable in certain cases:
use Params::Validate 'validate';
sub add2 {
my $self = shift;
my $args = validate (@_, { ... } );
}
3. Slightly less verbose code, for simple one-liners and/or anonymous functions: my $calc_functions = {
'add' => sub { $_[0] + $_[1] },
'subtract' => sub { $_[0] - $_[1] },
...
};
my $func = 'add';
$calc_functions->{$func}->($args);Re: Why I’m Learning Perl 6
#346Earlier quoted context omitted.
I don't know about others, but I personally have always seen Go as an internal language for Google. This made me feel like it was appropriate for projects that I personally control, but unlikely to be useful in a career. That's really just a feeling, though, and I recognize that if everyone felt like I do, it would make Go a niche language that was actually probably pretty lucrative to know. So I wouldn't say I'm put…
I can't speak for your location but I've found no shortage of companies choosing Go in London; from fintec through to online games. So it's definitely not a niche language used only by Google. I can understand other people's complaints about the language though.
Granted, in my area, there are exactly none, but I don't live in the best location for the use of modern tool/language/technology stacks. If I were to move an hour or two north, I'd probably find many.
Re: Why I’m Learning Perl 6
#347Even though this could more properly be called, "Why having language support for M:N thread multiplexing is important", I thought it was a refreshing article on why I might actually use a bit of perl6. Last year I attended a conference and saw Larry Wall speak. It was an overview of Perl 6 and I was completely underwhelmed. Larry spent about half the time talking about unicode support. It wasn't a boring talk, but I…
Better math is one good reason. Grammars are also a great feature of Perl 6.
From what I've seen perl6 makes some operations more convenient. Cool, I guess, but not a great reason to reach for perl6.
Grammars are really cool, and one reason I might reach for perl6, but you also have really great special-purpose tools like Antlr. I suppose I don't feel the need grammars that often to need them reified in my language of choice, but next time I need to do some parsing, however, I will probably play around with perl6.
Re: Why I’m Learning Perl 6
#348Earlier quoted context omitted.
> For long-running tasks, if they are I/O bound you can use non-blocking I/O and event loops. If they are CPU bound, then use threads or separate processes. The two techniques can be combined to scale well across multiple cores. One might suppose this to be the case, but to my knowledge only network IO is truly non blocking, although there are async io api's in some languages for disk reads/writes, they're still bloc…
Yeah, non-blocking disk I/O is painful. I've never had to write code that did enough disk reading/writing to try to parallelise it, so I've never researched the solutions that much. What I don't understand is why disk I/O should require a different API to be non-blocking. After all, network I/O can be blocking or non-blocking with the same read() and write() calls that disk I/O uses. There must be some reason why no…
Now, with NT, you have ReadFileEx() and WriteFileEx(). However, a user can call them in such a way such that the semantics are: "hey, try and read this, if you can do it immediately without blocking, great... if you have to block, then do whatever you need to do in the background to make that happen, but still return to me without blocking".
That, and that alone, is the key difference between the inherently synchronous I/O model of UNIX, and the inherently asynchronous I/O model of NT. The entire NT I/O subsystem, cache manager, driver API, memory management, APCs, scheduling et al is predicated around the notion of every I/O request being asynchronous.
If everything happens to be in the right spot at the right time, sometimes an I/O call can be synchronous (i.e. user->kernel->user without a context switch due to a required wait). In every other case, the kernel won't be able to complete it there and then, so, it checks to see if the user still wants that read or write call to return immediately -- which implies "asynchronous I/O" (referred to as "overlapped" I/O in NT parlance, because you're overlapping an I/O request with more compute).
Windows kernel drivers are fundamentally more complex than corresponding Linux drivers because the kernel's I/O model is fundamentally more sophisticated -- everything is packet driven (the "I/O request packet", or Irp), your driver's read/write entry points need to be able to query the incoming I/O request and determine if the user wants sync/async, how you need to return the call so that the I/O manager can furnish the correct behavior to all the other pieces of the subsystem (and potentially other drivers that are layered higher and lower), and a huge number of other subtle details.
The added complexity is required because the fundamental I/O model is asynchronous. In the UNIX synchronous I/O model, there's simply no semantic concept -- at both the driver level, kernel level, and APIs exposed to the user -- to say "here, read() this and return immediately -- if it can be done synchronously, great, if not, kick it off in the background and give me some opaque structure back I can use in the future to check on the completion of the operation".
The other huge advantage of NT is the notion of thread-agnostic I/O. That is, the thread that initiates one of these asynchronous read requests doesn't have to be the same thread that completes it. Although it sounds simple, that's one of those tip-of-the-iceberg technical things where there are so many pieces behind the scenes that need to cooperate to facilitate the functionality. I talk a little bit about thread-agnostic I/O here: https://speakerdeck.com/trent/pyparallel-how-we-removed-the-....
So, to summarize, all discussions regarding asynchronous I/O and M:N threading on UNIX are sort of fundamentally flawed because the underlying primitives can't express what is actually needed (an asynchronous I/O subsystem at the kernel level, thread-agnostic completion-oriented I/O, and ideally, thread pools + completion ports) to achieve the end goal: optimally using your underlying hardware :-)
(Optimal hardware usage necessitates one thread running per core, and the ability for any one of these threads to continue program logic upon completion of an I/O request, regardless of whether or not they were the thread to initiate that request.)
Re: Why I’m Learning Perl 6
#349Earlier quoted context omitted.
I can't speak for your location but I've found no shortage of companies choosing Go in London; from fintec through to online games. So it's definitely not a niche language used only by Google. I can understand other people's complaints about the language though.
Like I said, it's the belief that it's a niche language that's kind of making it a niche language - that is, fewer people know it (because of the perceived niche-ness), but more people want it, meaning the pay is good. I'm not at all surprised to hear there are quite a few shops using it. Granted, in my area, there are exactly none, but I don't live in the best location for the use of modern tool/language/technology…
* Are you saying you don't use it because you consider it niche?
* Or are you saying you believe people don't use it because they believe it is niche?
* Or is your point that Go is niche because people consider it to be niche so it never gains critical mass?
In any case, it's not niche. Period. It's being used lots by both start ups and more established businesses alike. I'm not saying it has the kind of penetration that Java or Python does, but Go is still definitely "mainstream" (for want a better description) these days.
Re: Why I’m Learning Perl 6
#350Earlier quoted context omitted.
For me, other than the fact that I don't need yet another Algol reimplementation in my life, I'm also not interested in code littered with error handling. Also strongly prefer FP.
I don't understand how some other language would not need to handle all the errors ? I have written code in go/java/php/python/js and error handling has been a majority chunk of lines in most if not all cases(in other cases the errors are just not handled). The best ideal case flow is always easiest to build.
Erlang and it's VM doesn't need error handling (edit: like the ones you listed).
You use pattern match and you match for the outcome you want. So every other state is a let it crash and burn cause you don't care. Because of this mentality you don't have to be God and figure out all the possible fail state to Error check.
The VM enable this type of thinking because it's preemptive. And also there are supervisor trees to resent your program state. The error check is in form of monitor and robustness I guess but it's not in the usual form of other popular languages like the ones you listed.
This is why I prefer Erlang over Go in concurrency. The BEAM VM is good. Also no generics.