Deutsch English Français Italiano |
<vbkpfc$27l2o$1@paganini.bofh.team> View for Bookmarking (what is this?) Look up another Usenet article |
Path: ...!weretis.net!feeder8.news.weretis.net!newsfeed.bofh.team!paganini.bofh.team!not-for-mail From: Waldek Hebisch <antispam@fricas.org> Newsgroups: comp.lang.c Subject: Re: Top 10 most common hard skills listed on resumes... Date: Sun, 8 Sep 2024 18:13:02 -0000 (UTC) Organization: To protect and to server Message-ID: <vbkpfc$27l2o$1@paganini.bofh.team> References: <vab101$3er$1@reader1.panix.com> <871q27weeh.fsf@bsb.me.uk> <20240829083200.195@kylheku.com> <87v7zjuyd8.fsf@bsb.me.uk> <20240829084851.962@kylheku.com> <87mskvuxe9.fsf@bsb.me.uk> <vaq9tu$1te8$1@dont-email.me> <vbci8r$1c9e8$1@paganini.bofh.team> <vbcs65$eabn$1@dont-email.me> <vbekut$1kd24$1@paganini.bofh.team> <vbepcb$q6p2$1@dont-email.me> <vbgb5q$1ruv8$1@paganini.bofh.team> <vbhbbb$1blt4$1@dont-email.me> <vbipp5$24kl5$1@paganini.bofh.team> <vbk0d9$1tajm$1@dont-email.me> Injection-Date: Sun, 8 Sep 2024 18:13:02 -0000 (UTC) Injection-Info: paganini.bofh.team; logging-data="2348120"; posting-host="WwiNTD3IIceGeoS5hCc4+A.user.paganini.bofh.team"; mail-complaints-to="usenet@bofh.team"; posting-account="9dIQLXBM7WM9KzA+yjdR4A"; User-Agent: tin/2.6.2-20221225 ("Pittyvaich") (Linux/6.1.0-9-amd64 (x86_64)) X-Notice: Filtered by postfilter v. 0.9.3 Bytes: 19276 Lines: 431 Bart <bc@freeuk.com> wrote: > On 08/09/2024 01:05, Waldek Hebisch wrote: >> Bart <bc@freeuk.com> wrote: > >>> Then you no longer have a language which can be implemented in a few KB. >>> You might as well use a real with with proper data types, and not have >>> the stack exposed in the language. Forth code can be very cryptic >>> because of that. >> >> First, it is not my goal to advocate for Forth use. > > You're doing a fine job of it! > > For me it's one of those languages, like Brainf*ck, which is trivial to > implement (I've done both), but next to impossible to code in. I wonder if you really implemented Forth. Did you implement immediate words? POSTPONE? > With Forth, I had to look for sample programs to try out, and discovered > that Forth was really a myriad different dialects. It's more of a DIY > language that you make up as you go along. Well, there is the standard and several implementations that do not follow the standard. As in each language implementations have their peculiar extentions. And Forth is extensible, so there are user extentions. > >> : 2*3 => >> ** 6 >> : 2, 3, *() => >> ** 6 >> the first line is infix form, '=>' oprator prints what is on >> the stack (but you cat treat it as "print current result"). >> In the second line two numbers are pushed on the stack and >> then there is call to multiplication routine. Parser knows >> that '*' is an operator, but since there are no argument >> '*' is treated as ordinary identifer and as result you >> get multiplication routine. Like in other languages parentheses >> mean function call. Up to now this may look just as some >> weirdness with no purpose. But there are advantages. One >> is that Pop11 functions can return multiple values, they just >> put as many values as needed on the stack. Second, one can >> write functions which take variable number of arguments. >> And one can use say a loop to put varible number of arguments >> on the stack and then call a routine expecting variable >> number of arguments. In fact, there is common Pop11 idiom >> to handle aggregas: 'explode' puts all members of the aggregate >> on the stack. There are also constructor function which build >> aggregates from values on the stack. > > This sounds like one of my bytecode languages. > > So, in the same way that Lisp looks like the output of an AST dump, > these stack languages look like intermediate code: > > > HLL -> AST -> Stack IL -> Interpret or -> ASM > (eg. C) (Lisp) (Forth) > (Pop-11) Well, in Pop11 it it more like reader parser HLL -> token stream -> Stack IL -> ASM or machine code in memory Both reader (responsible for turning characters into tokens) and parser are user extensible. For example, general addition is defined as: define 5 x + y; lvars x, y; if isinteger(x) and isinteger(y) then if _padd_testovf(x, y) then return() else -> endif endif; Arith_2(x, y, OP_+) enddefine; The '5' after 'define' means that we are defining an operator which have priority 5. 'lvars' says that 'x' and 'y' obey lexical scoping (one could use 'vars' to get dynamic scope instead). The 'isinteger' test check for machine-sized integers, if both 'x' aand 'y' are integers this takes fast path and uses machine addition (with check for overfolw). In case of no overflow the result of machine addition is return. Otherwise 'Arith_2' handles (hairy) general cases. Users can define their own operators. For example define 7 x foo y; y; enddefine; defines operator 'foo' (of higher priority than addition). And we can use it: : 1 foo 2 => ** 2 : 2 + 3 foo 4 => ** 4 : 2 + (3 foo 4) => ** 6 Naive Fibonacci routine may look like this: define fibr(n); if n < 2 then 1 else fibr(n - 1) + fibr(n - 2) endif enddefine; Note that use of the stack is invisible above, user may treat this as something like Pascal, only that source language structures must be terminated by verbose 'endif' and 'enddefine' respectively. OTOH there is no need for explicit return, last value computed is the return value. There are some anomalies, assignment is written as: a -> b; which means assign a to b. There is 'printf' which works like this: : printf(2, '%p\n'); 2 : printf(2, 3, '%p %p\n'); 3 2 Note that order of printed values is reversed compared to source and format comes last, this is due to stack semantics. You can write things like: external declare tse in oldc; void tse1(da, ia, sa, dp, ip, sp, d, i, s) double da[]; int ia[]; float sa[]; double * dp; int * ip; float * sp; double d; int i; float s; { } endexternal; The first line switches on syntax extention and lines after that up to 'endexternal' are parsed as C code. More procisely, 'oldc' expects KR style function definitions (with empty body). As result this piece of code generates Pop11 wrapper that call corresponding C routine passing it arguments of types specified in C definition (but on Pop11 side 'double da[]' and 'double * dp' are treated differently). Note that this in _not_ a feature of core Pop11 langrage. Rather it is handled by library code (which in principle could by written by ordinary user. > Most people prefer to code in a HLL. You mean "most people prefer by now traditional syntax", sure. > But this at least shows Lisp as > being higher level than Forth, and it's a language that can also be > bootstrapped from a tiny implementation. Pop11 has very similar semantics to Lisp and resonably traditional syntax. I would say that Lisp users value more extensibility than traditional syntax. Namely Lisp macros give powerful extensibility and they work naturaly with prefix syntax. In particular, to do an extension you specify tree transformation, that is transformation of Lisp "lists", which can be done conveniently in Lisp. In Pop11 extentions usually involve some hooks into parser and one need to think how parsing work. And one needs to generate representation at lower level. So extending Pop11 usualy is more work than extending Lisp. I also use a language called Boot, you will not like it because it uses whitespace to denote blocks. Semantics of Boot is essentially the same as Lisp and systax (expect for whitespace) is Algol-like. A sample is: dbShowConsKinds(page, cAlist) == cats := doms := paks := defs := nil for x in cAlist repeat op := CAAR x kind := dbConstructorKind op kind = 'category => cats := [x,:cats] kind = 'domain => doms := [x,:doms] kind = 'package => paks := [x,:paks] ========== REMAINDER OF ARTICLE TRUNCATED ==========