Personal pronouns: 同志 / 同志 / 同志的
Any second language used only for programming purposes is going to be doomed from the outset anyway. I work in a Chinese engineering firm. They work with Chinese people (and me). They sell their products to Chinese firms. What possible incentive could they have to make all their engineers use a different language than Mandarin to communicate in? If they grow to the point that international markets are a concern, they’ll have to i18n their products anyway (because their customers won’t be speaking some conlang!) and given the costs of that, updating the design documents in another language is a minor cost.
Conlang IALs are a solution in search of a problem for an overwhelming number of professionals. They present a high-cost initial barrier of entry (the time it takes to learn the conlang to fluency) with a very low payout in the short- and medium-term for almost all involved people. And even if the engineers in question did learn the conlang do you genuinely believe they’ll use it when doing work among other speakers of their own language? Do you genuinely believe the conlang will be the primary communication tool?
Idealism is a good thing. A great thing. Provided that it is, in some fashion, compatible with reality. A conlang IAL for programming is not compatible with reality.
I have found myself thinking this more and more as well, with the rising number of projects which are being developed primarily by/for speakers of other languages, sometimes with terrible to non-existent english support.
I love how this is always framed: “…terrible to non-existent English support…”
There’s about 400 million native English speakers in the world. There’s about a billion native Mandarin speakers in the world. Why is it never framed “…terrible to non-existent Mandarin support…”? There’s about 475 million native Spanish speakers in the world. Why is it never framed “…terrible to non-existent Spanish support…”?
Even the way internationalists frame things is very telling.
I’m referring to 16 years of experience teaching language and seeing where the pain points were in acquiring English from Mandarin speakers. The irregularity of English grammar was never a particularly difficult point. The Chinese just sat and memorized, something they’re good at from just their own orthography, given that it’s almost, but not quite, entirely devoid of system.
What were pain points were conceptual pain points. Most people couldn’t grasp articles and when they should or should not be used. (Esperanto has an article whose use case is bizarre.) Most people had a hazy grasp on verb conjugation, freely using whichever conjugation first passed their lips without subject/verb agreement. Declining for number was a pain point. Even the mildest amount of gendered language caused problems (“he” and “she” tend to get used interchangeably and fluidly, often switching between them in the same sentence). Verb tenses. Verb aspects. Both of these caused tremendous difficulty.
And Esperanto has all of them and more.
Would Esperanto be easier than English to learn? Of course! It’s far more regular than English. But the point here is that while easier than English, it’s not much easier than English because as a language at a conceptual level it is not that different from English. And then on top of that the consonant clusters (thank you Polish!) would render it nigh-impossible to pronounce. We’re talking about people for whom the word “lonely” is a tongue-twister because of the switch between ‘l’ and ‘n’. For whom the “str” in “string” is a pain point. And I’ve spotted Esperanto words with five-consonant clusters, four of them hard.
There is not much difference in terms of difficulty between learning English for Mandarin speakers and learning Esperanto because the difficulties come from conceptual levels, not practical. There are alien ideas in Esperanto (shared with English), and that’s where the hard part comes. So the choice of a Chinese speaker is to learn Esperanto and get (generously) a million people (of eight billion) to speak with, or get (equally generously) 1.5 billion people (of, remember, eight billion) to speak with.
When that stark calculus is presented, the choice is clear: spend the little bit of extra work it takes to learn English and ignore Esperanto.
I’d be very interested in seeing your mentioned studies, incidentally. Specifically seeing who performed them (and what their methodology was). My guess is that they weren’t professional linguists, and nor were they particularly rigorous (using things like self-selected subjects, etc.).
It’s rather obvious you don’t see what I’m talking about. Even when you QUOTE IT.
English, to take a horrifically terrible language at random, is not much harder to learn for, say, a Chinese speaker
That is a sweeping generalization you made. How would Esperanto be harder for a Chinese person than English?
See that there, Sparky? That’s you claiming I said the precise opposite of what I said.
(Note, also, that I very clearly called English a “horrifically terrible language” yet the rest of your response to that was acting as if I said English were a good language. Another sign of not reading for comprehension, but rather reading to find some excuse to react even if you have to make up that excuse.)
So go back and re-read everything … EVERYTHING … I said for comprehension before you waste any more of my time. I’m tired of intellectually dishonest Esperantists.
Dude, I said English was harder. Seriously, try to keep up! I just said it’s not much harder and comes with the benefit of people actually speaking it so that learning it isn’t a waste of effort.
Further, Esperanto is ignored because it’s not much easier than natural languages to huge swathes of the world’s population, but at least has the benefit of being utterly useless to learn.
Learn a few languages from places that aren’t Indo-European ones. Learn how you can have grammars with little to no declension, for example: no verb tenses, aspects, voices, genders, cases … not even declining by count. Then consider:
On top of this:
And I’m out of steam already. There are a whole lot of hidden linguistic assumptions in Esperanto that are alien to language speakers from outside of the Indo-European milieu, or difficult for such speakers to actually perform. To someone in steeped an Indo-European linguistic environment these are invisible. They’re “natural” or even “logical”. But they are absolute tongue-twisters and conceptual mountains for those coming from outside of those environs. And if you’re going to climb those conceptual mountains and twist your tongue in service of these phonetic horrors, where do you think it’s best to expend your efforts:
If you’re sane and value your time, you pick literally almost any natural language in the world for better return on investment, even though it may, in the case of some of those (coughIndo-Europeancough) languages, be a little bit more difficult than Esperanto. (Yes. A little bit.)
Esperanto is not a particularly easily learnable language to most of the world. It’s a very parochial language made by someone whose exposure to language was all European and very strongly focused on specifically East European languages both phonetically and grammatically. English, to take a horrifically terrible language at random, is not much harder to learn for, say, a Chinese speaker than Esperanto would be, but it would be a million times more useful given the rather pathetically small number of Esperanto speakers out there.
If you’re going to use a constructed IAL (as opposed to de facto lingua francas like have been historically the case), make one that isn’t filled with idiotic things like declension by case, by gender, by number, by tense, by … Or you’re going to have most people in the world ignoring it. Like you already have for Esperanto.
Futhark is of interest as a future direction, chiefly as a supplementary language for sub-pieces of a larger, performance-intensive program. Note that its creators, however, explicitly state:
Futhark is not intended to replace existing general-purpose languages. The intended use case is that Futhark is only used for relatively small but compute-intensive parts of an application.
This is not a negative point, incidentally! I personally use a lot of languages in my work because I find it’s better to use a tool honed to near-perfection for a particular use case than it is to employ another tool that does something not quite the same with lower quality. I wish more programmers learned more tools so they stopped doing the programming equivalent of hammering nails with a large wrench.
Lisp is “functional-enabling” not a functional language. Take a look at the Common Lisp library and you’ll see a whole lot of imperative-nature constructs and code in it. Lisp permits (and to a degree supports) functional programming. It does not enforce nor even default to the functional paradigm.
And even in a Lisp you’re going to start hitting the boundaries of your kit in the embedded world when you do partial application, closures, and even something as seemingly trivial as using immutable state. You’ll wind up fighting the language more often than fighting your problem domain and the result will be counterproductive.
Best of breed for me in embedded space is Ada (with Modula-3 being another decent choice). Lisp’s not even in the display hall.
OK, let’s take that weird one apart so I can show you the strategy for reasoning about it: Index'Pos(Index'Succ(Index'First));
First, Index'Pos
is clearly separating two lexical items: Index
and Pos
. Where have we seen either of those before? Pos
is only ever used on the right hand side of '
, so that’s a clue that this is some kind of component of Index
. Index
is defined, however. Let’s take a look at that specification again.
generic
type Element_Type is private;
type Index is (<>);
type Collection is array(Index) of Element_Type;
with function "<=" (Left, Right : Element_Type) return Boolean is <>;
procedure Gnome_Sort(Item : in out Collection);
Index
is a type. What type? (<>)
. That’s just gibberish if you only know Python and C, but we can still tease out some information.
First, Index
has a name that means something. It’s, well, an index. And if we look at Collection
right underneath it, it’s an index into an array. So Index is likely an integer.
So 'Pos
is some kind of operation or member or something on the type of an integer. And it suggests that it means some kind of position. What could “position” mean to an integer?
The clue lies in how the function there gets used. I didn’t put it there (because I was already being long-winded) but here’s the example of using that:
with Gnome_Sort;
with Ada.Text_Io; use Ada.Text_Io;
procedure Gnome_Sort_Test is
type Index is range 0..9;
type Buf is array(Index) of Integer;
procedure Sort is new Gnome_Sort(Integer, Index, Buf);
A : Buf := (900, 700, 800, 600, 400, 500, 200, 100, 300, 0);
begin
for I in A'range loop
Put(Integer'Image(A(I)));
end loop;
New_Line;
Sort(A);
for I in A'range loop
Put(Integer'Image(A(I)));
end loop;
New_Line;
end Gnome_Sort_Test;
And here the penny drops. The Gnome_Sort
routine is generic (clue: generic
in the specification). The index has to be defined for it. We do that with the three lines immediately after the procedure
line in the use case. Index
is an integer in the range of 0…9.
Because the Gnome_Sort
procedure is generic, we make no assumptions about what the array ranges are: here it’s 0…9, but it could just as easily have been -1277516794231…125164987325159876. So these 'Pos
, 'First
, and 'Last
and 'Val
and such things are used to step through loops in a type-safe way that’s guaranteed to never step out of the array boundaries.
But it’s largely unimportant. These are Ada-isms focused on Ada’s obsession: correctness. That’s just line noise, really, for purposes of understanding the code. We can kind of intuit that I is starting from the successor ('Succ
) of the first ('First
) (a.k.a the second) element of the array and going through it until it reaches the end of it (<= Index'Last
). This guess is further bolstered by the comparison of things indexed via I - 1
against I
.
Decoding this is a dollop of familiarity with paradigms and coding approaches and decent contextual guessing. Is it better to just know the language? Yep. But even not knowing it you can tease out everything you need to work out how a gnome sort works. Part of the skill set in reading alien code is to learn how to relax and gloss over the bits that you don’t understand until you see the shape of the whole thing, after which, if you’re familiar with the paradigm, you can start making very good guesses as to what the unfamiliar bits actually mean. (Again, if you’re unfamiliar with the paradigm you’re … going to need to learn.)
Learn more languages, especially cross-paradigm. Most languages in a given paradigm will be sufficiently similar that you can get the gist of any code written in it if you’re familiar with another language of the paradigm, especially if the code is reasonably written. For example:
(specification)
generic
type Element_Type is private;
type Index is (<>);
type Collection is array(Index) of Element_Type;
with function "<=" (Left, Right : Element_Type) return Boolean is <>;
procedure Gnome_Sort(Item : in out Collection);
(body)
procedure Gnome_Sort(Item : in out Collection) is
procedure Swap(Left, Right : in out Element_Type) is
Temp : Element_Type := Left;
begin
Left := Right;
Right := Temp;
end Swap;
I : Integer := Index'Pos(Index'Succ(Index'First));
J : Integer := I + 1;
begin
while I <= Index'Pos(Index'Last) loop
if Item(Index'Val(I - 1)) <= Item(Index'Val(I)) then
I := J;
J := J + 1;
else
Swap(Item(Index'Val(I - 1)), Item(Index'Val(I)));
I := I - 1;
if I = Index'Pos(Index'First) then
I := J;
J := J + 1;
end if;
end if;
end loop;
end Gnome_Sort;
There’s a gnome sort (a.k.a. stupid sort) in Ada. If you’re familiar with any loosely structured-imperative programming language you can pretty much figure it out. while
works as you’d likely expect. if
and else
too. loop
and end loop
and end if
and even begin
/end
are pretty obvious. You’ll have to do a bit of head-scratching if you’re not familiar with languages in the Wirthian tradition (Pascal, the Modulas, the Oberons) to figure out which parts you can safely ignore and which parts you need to pay attention to, but it’s not really difficult. The hardest part is “weird” expressions like Index'Pos(Index'Succ(Index'First));
which you can still kind of guess the meaning of from context, especially in the later expression while I <= Index'Pos(Index'Last)
where you might think Index`Pos() is like index.pos() in another language like Python or C++ and won’t be completely wrong (though still wrong).
Basically you work it out by knowing the paradigm and knowing how things are generally expressed in said paradigm.
Of course if you’re unfamiliar with the paradigm involved you might find it impossible to decode:
(Erlang—functional)
gnome(L, []) -> L;
gnome([Prev|P], [Next|N]) when Next > Prev ->
gnome(P, [Next|[Prev|N]]);
gnome(P, [Next|N]) ->
gnome([Next|P], N).
gnome([H|T]) -> gnome([H], T).
If you know another functional language like SML or Haskell or the like, this will be easy enough to read. Even if you know some logic languages like Prolog this is simple enough to follow. If you only know imperative languages (unstructured, structured, OOP, etc.), however, this will be gibberish.
(Forth—concatenative)
defer precedes
defer exchange
: gnomesort ( a n)
swap >r 2 tuck 1- ( c2 n c1)
begin ( c2 n c1)
over over > ( c2 n c1 f)
while ( c2 n c1)
dup if ( c2 n c1)
dup dup 1- over over r@ precedes
if r@ exchange 1- else drop drop drop >r dup 1+ swap r> swap then
else drop >r dup 1+ swap r> swap then
repeat drop drop drop r> drop
;
:noname >r cells r@ + @ swap cells r> + @ swap < ; is precedes
:noname >r cells r@ + swap cells r> + over @ over @ swap rot ! swap ! ; is exchange
Although Forth is technically an imperative language, it is a very weird one with its stack discipline and unless you know it, or know related concatenative languages like Factor, this is going to be totally brain-damaging.
So in cases where you’re unfamiliar with the paradigms involved: learn the paradigms. You should learn a new paradigm of programming every couple of years if you’re a serious programmer, after all.
Which industry?
Programming is more than just writing Yet Another CRUD-backed data-siphoning web app. It’s more than supercomputing/high performance computing. It’s more than spreadsheets and word processors. It’s more than games.
Any one of those fields I mentioned are effectively a completely separate industry from the others. And I haven’t even touched the 500kg gorilla of embedded systems that outnumber all of those put together by an order of magnitude or two.
Some software industries (the web stuff, say, or user-facing software like spreadsheets and word processors) will find pure functional or major steps along that path to be useful and an improvement over current techniques. Others (high performance computing, games) will find themselves stepping backward if they go the full-functional route. And that 500kg gorilla I mentioned simply can’t use functional programming. (Hell, I don’t think there’s a pure-functional runtime that fits into any of the kit I work on, not to mention the runtime plus an actual application. I’m willing to be corrected, though: if there’s a functional language out there that will let me write non-trivial applications that fit in 256KB code space and 48KB dynamic data space, I’m eager to hear about it!)
However much you think you know about software development, be aware that it’s far larger than you think. (This applies to me too. I haven’t even glanced at financial or health software’s direction, and only have very vague notions of what aerospace systems entail.) And as a result, different tool sets are required for different problem domains. Functional doesn’t fit them all.
It looks sane (by comparison) until you look into its semantics and hit this rabbit’s warren of weird-ass design decisions. And then compare how it is written in theory (like with full names of things) vs. in practice (executable line noise).
BANCStar looks very bad, but much of that, I suspect, is chiefly because it’s undocumented, making it hard to figure out what some of the magic numbers, etc. are. MUMPS is fully documented and still write-only (and only barely writeable!).
This one line says it all for me: