Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
UNIX way, C, LISP et al.
View unanswered posts
View posts from last 24 hours

Goto page Previous  1, 2  
Reply to topic    Gentoo Forums Forum Index Gentoo Chat
View previous topic :: View next topic  
Author Message
steveL
Watchman
Watchman


Joined: 13 Sep 2006
Posts: 5122
Location: The Peanut Gallery

PostPosted: Sat Jul 07, 2018 9:03 pm    Post subject: Reply with quote

CasperVector wrote:
khayyam strongly argued that freedom is by nature a socio-political issue; I still do not agree with him on details here and there, but important is that I realised that I am very bad at socio-political issues.
Heh, the road to enlightenment begins with realising how little one knows..

That wasn't just khayyam's position btw; I stated it too, only in passing as this was meant to be a more technical conversation, which is why I split the topic in the first place. That is what I meant by "You cannot solve sociopolitical problems via technical solutions to something completely different."
WRT software, computing has never operated in a vacuum (or we'd have no data to work on.)

What khayyam said about fraud was apposite, because, if you are thinking about the socio-political, it is important to know exactly how the world really works, despite what the middle-classes like to think.
The "economic" system we are forced to live under (and I use "forced" deliberately, as wars have been, and are, triggered to keep it dominant) is a complete and utter fraud.
The term I recall for this (from my rather privileged upbringing) is: "the Mechanism".

It's "not personal", and "the mechanism will provide", for us few who happen to be connected to the spigot.
CasperVector wrote:
Had we both been more explicit in the wording, we would have avoided the displeasure; I really hope there is a research field/subfield about saving good-natured people from this kind of harmful implicity in debates.
Well, the flip side of it is that khayyam really does know how to type the hind-leg off a donkey. ;-)
You're right: we're all good-natured, by default, so we can just get along, and move past this kind of thing.
CasperVector wrote:
if C used S-expressions, it would be much easier to implement structural macros, and then C with classes / templates / zero-cost abstractions would be probably just gymnastics with the macros; however, this is not the case, and now we end up with C++ with its increasing burdens^Wfeaturesets.
I know what you mean about hygienic macros. But really, this is just about correctly stacking (or scoping) during eval.
For instance bash is "slippery" in arithmetic, in that it keeps evaluating, and correctly handles each value in its "own" brackets:
Code:
a=5 b=7 x='a + b'; echo $(($x * 6)) vs $((x * 6))
Notice the order of evaluation is correct, following mathematical precedence as written, unlike a C macro; unless we explicitly tell it to expand as string.

This is just top-down recursive evaluation, so the computer tracks the stack for us, and is where everyone starts out.
You need to bootstrap something with top-down evaluation; the simplest thing to take on is lex, since there are only two precedence levels really (alternation and concatenation, possibly starred.)
Simplest of all, ofc, is just to use the toolset as intended.
Back to top
View user's profile Send private message
CasperVector
Tux's lil' helper
Tux's lil' helper


Joined: 03 Apr 2012
Posts: 94

PostPosted: Sun Jul 08, 2018 5:54 am    Post subject: Reply with quote

steveL wrote:
I know what you mean about hygienic macros. But really, this is just about correctly stacking (or scoping) during eval.
For instance bash is "slippery" in arithmetic, in that it keeps evaluating, and correctly handles each value in its "own" brackets:
Code:
a=5 b=7 x='a + b'; echo $(($x * 6)) vs $((x * 6))
Notice the order of evaluation is correct, following mathematical precedence as written, unlike a C macro; unless we explicitly tell it to expand as string.
This is just top-down recursive evaluation, so the computer tracks the stack for us, and is where everyone starts out.
You need to bootstrap something with top-down evaluation; the simplest thing to take on is lex, since there are only two precedence levels really (alternation and concatenation, possibly starred.)

I see, and what you say is very enlightening. I think the most elegant aspect of Scheme is that it minimises the macro mechanism, and you can safely do, in macros, most things the language itself allows.
One tiny example. Laurent has advised against using the `printf'-family of functions, due to their runtime inefficiency. This would be unnecessary, if they were just cleanly expanded macros.
And one large example. See how the powerful (even more so than Haskell, at least according to one PL expert) type system in Typed Racket is built using only Racket with its macros.
These are examples that are impossible (almost for the former, definitely for the latter) without structural macros. Which is why I believe homoiconicity does practically and dramatically reduce the linguistic complexity.

steveL wrote:
Simplest of all, ofc, is just to use the toolset as intended.

I am not at all opposing to learning the current toolset. Actually I use quite a lot of them, and like many of them, more or less. (Or otherwise what forums would I be in? ;)
But I also advocate for the research of an elegant unified linguistic foundation that applications (more or less) isomorphic to the current ones can be built on.
This is not to pursue a One True Way, but to pursue a minimalist greatest common divisor. In other words, the Unix philosophy blossoming in the languages used to build our systems.
_________________
My current OpenPGP key:
RSA4096/0x227E8CAAB7AA186C (expires: 2020.10.19)
7077 7781 B859 5166 AE07 0286 227E 8CAA B7AA 186C
Back to top
View user's profile Send private message
steveL
Watchman
Watchman


Joined: 13 Sep 2006
Posts: 5122
Location: The Peanut Gallery

PostPosted: Sun Jul 08, 2018 2:49 pm    Post subject: Reply with quote

CasperVector wrote:
I think the most elegant aspect of Scheme is that it minimises the macro mechanism, and you can safely do, in macros, most things the language itself allows.
Indeed. I concur that functional languages have the best macros.
A tiny part of me insists that's because they have to ;) but that doesn't change the value of the approach.

The thing I would like to get across is that in its own way, shell has shown the best approach to handling strings, at least in my experience.
Again, this might be because it had to, but a better way to see it is that each has focussed on doing the one thing well.

In doing so, they have nurtured the specific approach, into polished elegance. And yes, it is best if the macro language and the implementation language are one and the same, I totally agree with that.

Let's just be careful not to knock C, because to do so is to misunderstand the level it works at. Have a read of Lions' on UNIX
to see what I mean. (You won't be able to read it in one go; you will come back to it over years.)
The commentary is wonderful, but I recommend Bach's "The Design of the UNIX Operating System" along with it.

The point being, the level of CPP is when we have an assembler (which might be manual to start with) and a minimal compiler, and we don't want to use magic numbers, but symbolic defines, that the compiler sees as constants.
This is in the days before we had 'enum' and indeed any type-checking, and a vastly reduced address-space, 64KB, with much less actual RAM. And we have to write the core OS, before we can actually use a toolchain in any comfort, and we need to build the linker and loader before we can do that.
All we really have is an assembler, and the ability to start the output once we load it to core.

Now, sure, we can just write a small lisp interpreter. But that's not going to help us code to asm, only to continual evaluation, by definition; and it doesn't express how we actually think (it was never meant to, so that's not a criticism.)

Before we can get to a nice environment where everyone can express themselves, we need a way to keep our asm-level code portable, and that, like it or not, is C. It is not meant to be at a higher-level; it is meant to provide the foundation on which we build such levels.
And that has been proven, first with sh, then make, lex, yacc and awk, and all the languages that have flowed from there.

This does not take anything away from other computing, or other strands like Forth, COBOL, SNOBOL, Pascal, Modula and ADA.
Computers do not compete like humans do. They simply get on with it, and know zero about the outside world, only about the bit patterns in front of them, at CPU level.
CasperVector wrote:
One tiny example. Laurent has advised against using the `printf'-family of functions, due to their runtime inefficiency.
Hmm I cannot agree with that stance, so I checked the page.
I couldn't find any reasoning in support of that position; indeed the facility quoted relies on vsnprintf, which is a lovely function, ime.
It (and the pair snprintf) was standardised in C99, but the approach was proven in C95 (C89 Amendment 1, from Sep 1994) with swprintf (and they really should have added snprintf at the same time.)
CasperVector wrote:
This would be unnecessary, if they were just cleanly expanded macros.
They are in fact an example of a "little language", as Kernighan and Pike put it. Read Chapter 9 of "The Practice of Programming", for more discussion.
Not that I disagree with you on macros, or indeed overuse of printf.
People don't seem to know that puts is effectively "writeln" from other languages. So you see a lot of: printf("%s\n", "some literal"); which really annoys me on an efficiency level, and more so on the ignorance of return value, especially when I see it in books.
CasperVector wrote:
And one large example. See how the powerful (even more so than Haskell, at least according to one PL expert) type system in Typed Racket is built using only Racket with its macros.
These are examples that are impossible (almost for the former, definitely for the latter) without structural macros. Which is why I believe homoiconicity does practically and dramatically reduce the linguistic complexity.
Couldn't get that page to load; will come back to this when my head is not quite so tired.
CasperVector wrote:
I advocate for the research of an elegant unified linguistic foundation that applications (more or less) isomorphic to the current ones can be built on.
Well, just start with yacc and lex, and explore parsing a LISP, which is ofc trivial, and build up from there.
You need to read the awkbook, if you haven't ("The AWK Programming Language".)
awk is what Aho and Weinberger (of the dragon book, and papers on underlying theory) did next, with Kernighan, ie: the discoverers of what is now taught as Core Computing Theory.
Their book lays out fundamental algorithms (again not surprising given Aho's involvement), and shows just how useful #awk is.

You can tell, once you've used both awk and lex for any length of time, that awk is designed for prototyping, so that you can just copy the pattern from the awk script, directly to lex. Consider: #define length yyleng ("length" is an awk builtin.)
It's practically an evaluation front-end to lex and yacc. As sh is to C, in fact.

It really is a beautiful approach, and wonderfully elegant, ime

The underlying principle is ofc an old one: separate out whatever you do into functional layers, that build on each other, and allow you to switch modes as appropriate to the problem.
You only drop down below the convenience layer, once you have worked out the overall approach at the O(N) level, ie algorithmically.

Working that out is the largest, and surprisingly the hardest, part of the programmed design.
It is difficult because it is always so easy to get lost in "complexity of one's own making."

So working at a functional level, with sparse clean code, that only does what it needs to, is the only way to keep focus.

Optimisation comes much later: once you actually have some feedback from usage, and only after you've actually got it working correctly.
Most software projects don't even reach that state for a few years, both in FLOSS and commerce.

So it's odd that people focus so much on "big datasets" and "multi-parallel" approaches, when seemingly everything they implement
and publish, doesn't even work properly to begin with.
Quote:
This is not to pursue a One True Way, but to pursue a minimalist greatest common divisor. In other words, the Unix philosophy blossoming in the languages used to build our systems.
Sounds cool.
But you need experience of the tools, to be able to implement any such thing, and the only way to get that is by doing (if you haven't already.)

The best intro to yacc (a true goldmine, in fact) is chapter 8 of UPE ("The UNIX Programming Environment"), again from Kernighan (& Pike). Indeed, Kernighan's reference awk implementation even has a couple of the same variable names as the code there.
I highly recommend "Lex & Yacc" (1992) by Levine, Mason and Brown; it provides insight into the background, when POSIX was only just standardised (so you could not rely on its build flags, -b and -p.)
By all means get the later one on flex, too.

Like I said, and as you know, it is trivial to lex and parse a functional language, so I'd like to see what you come up with, in say a year or so.
I am not saying "show us the code" blah blah; I am saying: Show us what you mean, in a yacc grammar file.
Back to top
View user's profile Send private message
CasperVector
Tux's lil' helper
Tux's lil' helper


Joined: 03 Apr 2012
Posts: 94

PostPosted: Wed Jul 11, 2018 12:08 pm    Post subject: Reply with quote

steveL wrote:
Let's just be careful not to knock C, because to do so is to misunderstand the level it works at.
The point being, the level of CPP is when we have an assembler (which might be manual to start with) and a minimal compiler, and we don't want to use magic numbers, but symbolic defines, that the compiler sees as constants.
This is in the days before we had 'enum' and indeed any type-checking, and a vastly reduced address-space, 64KB, with much less actual RAM. And we have to write the core OS, before we can actually use a toolchain in any comfort, and we need to build the linker and loader before we can do that.
All we really have is an assembler, and the ability to start the output once we load it to core.

These seem to be even less than the minimal requirements for Unix v6, and most (perhaps more than three nines?) embedded devices now enjoy vastly more resources than these.
I still admire what Unix pioneers achieved with such extremely limited resources, which I would not even dear to dream about.
However, we should also reconsider the restrictions put by these limits on consistency and completeness of the languages.
(I think this also follows what the original author of "worse is better" latter suggested.)

steveL wrote:
Now, sure, we can just write a small lisp interpreter. But that's not going to help us code to asm, only to continual evaluation, by definition; and it doesn't express how we actually think (it was never meant to, so that's not a criticism.)
Before we can get to a nice environment where everyone can express themselves, we need a way to keep our asm-level code portable, and that, like it or not, is C. It is not meant to be at a higher-level; it is meant to provide the foundation on which we build such levels.
And that has been proven, first with sh, then make, lex, yacc and awk, and all the languages that have flowed from there.

There are Scheme compilers, and some of them are really decent, both in terms of efficiency and elegance, eg. Chez Scheme which has recently been open-sourced.
Chez Scheme can self-compile in seconds, and produces code that sometimes outperforms C, and the implementation is much smaller than GCC or LLVM.
I guess a decent Scheme compiler could be made from the assembler through Forth, a minimal (without GC or other advanced features) Scheme interpreter, and then a minimal Scheme compiler.
(BTW, note that this might also minimise the hazards of "trusting trust", as one would begin with the bare assembler.)

steveL wrote:
Hmm I cannot agree with that stance, so I checked the page.
I couldn't find any reasoning in support of that position; indeed the facility quoted relies on vsnprintf, which is a lovely function, ime.
They are in fact an example of a "little language", as Kernighan and Pike put it.

I find this very understandable, since Laurent emphasises minimalism more than most people. Remember his reluctance to implementing virtual dependencies in s6-rc? They are still unsupported as of now.
Many thanks for the hint on little languages; I think structural macros will certainly help to reduce runtime overhead of little languages, perhaps in the cost of code sizes.
(But we might be able to teach the preprocessor to arrange a one-time expansion for some kind of "compressed" code, so we might still win in terms of both time and space complexity.)

steveL wrote:
Well, just start with yacc and lex, and explore parsing a LISP, which is ofc trivial, and build up from there. [...]

I see, and many thanks for the helpful advices. I am interested in how you would respond to following opinion by the PL expert I mentioned previously, which was also a student of Dan Friedman.
"State-of-the-art compiler courses care very little about parsing; compiler optimisation, including code compression, instead of parsing, is the main subject of compiler techniques."
"Syntaxes of mainstream languages (including Haskell) make parsers hard to write and make the languages hard to transform, for really few benefits."
"By using S-expressions, Lisp is easy to parse, and it is easy to implement code transforms from one well-defined 'language' into another well-defined 'language'."
(Disclaimer: I do not consider myself knowledgable enough to be able to say which approach is better, so I just rephrase and ask for opinions from those who are knowledgable.)
Chez Scheme (by R. Kent Dybvig, a former colleague of Dan Friedman, which also taught the above-mentioned PL expert) does its work in multiple tiny passes, thanks to the elegant expressiveness of S-expressions.
One of my hobby projects, a code generator for s6-rc, also used this idea, using the Unix directory hierarchy as the "intermediate representation".
(More importantly, Chez Scheme inspired nanopass; incidentally, the name of one author of nanopass can be abbreviated into "AWK".)

steveL wrote:
But you need experience of the tools, to be able to implement any such thing, and the only way to get that is by doing (if you haven't already.)
Like I said, and as you know, it is trivial to lex and parse a functional language, so I'd like to see what you come up with, in say a year or so.
I am not saying "show us the code" blah blah; I am saying: Show us what you mean, in a yacc grammar file.

As you might have already guessed, I would do not deny that I have not written a single compiler, perhaps except for the s6-rc code generator mentioned above.
(I also wrote a calculator for the types of enemies in a Plants vs. Zombies game level, using lex and yacc, but I guess that is even less of a compiler...)
(Nevertheless, I consciously used constant folding and dead-code elimination in reagent, another one of my hobby projects, which mainly focused on refactoring and code simplification.)
I do not doubt that a fraction of what I imagined would be impractical, but I do believe that what I think, generally, about homoiconicity, etc., might be enlightening to some real experts.
I would certainly try what you suggested, but I am not major in computer science, and would not necessary have a programming-related job, so perhaps I can only say "let's see what will happen".
_________________
My current OpenPGP key:
RSA4096/0x227E8CAAB7AA186C (expires: 2020.10.19)
7077 7781 B859 5166 AE07 0286 227E 8CAA B7AA 186C


Last edited by CasperVector on Thu Jul 12, 2018 10:39 am; edited 14 times in total
Back to top
View user's profile Send private message
John R. Graham
Administrator
Administrator


Joined: 08 Mar 2005
Posts: 10091
Location: Somewhere over Atlanta, Georgia

PostPosted: Wed Jul 11, 2018 2:04 pm    Post subject: Reply with quote

steveL wrote:
... The best intro to yacc (a true goldmine, in fact) is chapter 8 of UPE ("The UNIX Programming Environment"), again from Kernighan (& Pike). Indeed, Kernighan's reference awk implementation even has a couple of the same variable names as the code there.
I highly recommend "Lex & Yacc" (1992) by Levine, Mason and Brown; it provides insight into the background, when POSIX was only just standardised (so you could not rely on its build flags, -b and -p.)
By all means get the later one on flex, too. ...
I can also recommend flex & bison by Mason. Very readable.

- John
_________________
I can confirm that I have received between 0 and 499 National Security Letters.
Back to top
View user's profile Send private message
steveL
Watchman
Watchman


Joined: 13 Sep 2006
Posts: 5122
Location: The Peanut Gallery

PostPosted: Sat Jul 14, 2018 11:11 am    Post subject: Reply with quote

CasperVector wrote:
I still admire what Unix pioneers achieved with such extremely limited resources, which I would not even dear to dream about.
However, we should also reconsider the restrictions put by these limits on consistency and completeness of the languages.
There was none. Remember, LISP was conceived and implemented under even less resource.

You are still conflating a portable assembler, a necessary first-step, with languages dependent on a userland running on top of the base provided by, and implemented in, that portable asm.
Until you make that distinction in your mind, and see where having that distinction leads, you will continue to muddle what is clear.

Computing is not solely about computation: first and foremost, it is about the results.
IOW: "side-effects" are the whole bloody point. (This comes up a lot with functional programmers.)

That is not to say that a LISP, or other language, cannot be used in implementation of the base; just that there is no real point, since it's already covered, and in a way that actually suits how we prefer to express ourselves. (and without a load of self-styled "purists" complaining about all the "side-effects" everywhere.)

Before you argue on this, you should read "Syntactic Structures" (Chomsky, 1957) which is the theoretical underpinning of all computer languages. It will also help your work in yacc.
I understand that you don't agree with me on "how we prefer to express ourselves", because you prefer to express yourself in FP.
First read that book, and then read it again a couple of weeks later. Then we can discuss.
steveL wrote:
Hmm I cannot agree with that stance, so I checked the page.
I couldn't find any reasoning in support of that position; indeed the facility quoted relies on vsnprintf, which is a lovely function, ime.
They are in fact an example of a "little language", as Kernighan and Pike put it.
CasperVector wrote:
I find this very understandable, since Laurent emphasises minimalism more than most people.
That may well be, but I have just pointed out a contradiction between what you wrote above, and the reference you provided in support.
Without making a big deal about it, it behooves you to explain the contradiction, withdraw the remark, or otherwise explain the relevance of the reference or what you meant while conceding the reference does not support your statement.
CasperVector wrote:
Remember his reluctance to implementing virtual dependencies in s6-rc? They are still unsupported as of now.
While I agree with what he wrote there about only using one service for dnsproxy, I do not agree with him in not supporting "provides" (in openrc terms.)
It is not a disjunction; it is a set of alternatives, one of which must have been/be provided in some form or another, for the dependency to be fulfilled. (Yes, I realise that a set of alternatives is a "disjunction" in propositional logic. This is not propositional logic.)
This is nothing radically new (it's effectively an "alias"); it dovetails quite easily into a dependency resolver.

It is also relatively constrained in the openrc/initd space, since admins only want one "net" provided, even if they have several interfaces (which is less common) and further, dhcpcd takes care of everything when it comes to net. (if we are talking "next-gen" design, though ofc it's been around for about a decade that I recall, which means longer.)
The same applies to admin-configured "provides". (constrained.)

The admin knows what they're doing, much better than the developer who is not even present, by definition. Our job is solely to point out inconsistencies, and report status of monitored jobs; never to try and make up policy.
Defaults are for QA and distributors to worry about. Again, not our job, so let's not muck it up for those to whom the task does, and will always, fall: bug-wranglers and admins.
SEP ("Somebody Else's Problem") is the best conclusion of all, ime. It means: "I don't have to worry about this." :-)

Headspace is the most valuable asset a programmer has, since "Thinking is 70% of the game."

That is why commercial distros and the Microshites of this world, including Crapple, all try to capture "developer mindshare"; because they know it is a limited resource, and people tend to work with what they already know.
(That they're filling our heads and the Net with garbage is irrelevant to the only purpose: to transfer wealth in their direction.)

This above all, is why we must brush aside that tendency to accept without question, before we can even begin to approach a problem-space. Anything else means surrendering half our most vital resource to prejudice and its tedious ongoing maintenance, before we have started.

And that is not delivering our best.
Even if one doesn't care about end-users (in which case, we don't want to work with you), the end-product will be outstripped by other implementations, from less obnoxious cultures.
CasperVector wrote:
Many thanks for the hint on little languages.
The hint was intended to get you to read the book. ;) If it does that, it served its purpose.
CasperVector wrote:
I think structural macros will certainly help to reduce runtime overhead of little languages, perhaps in the cost of code sizes.
I doubt this; the whole point of these little languages is that the code is already present, in the library function that handles the format, and the format encapsulates more work if we did it ourselves.
Your implementation cannot add less code than none at all.
CasperVector wrote:
.. we might be able to teach the preprocessor to arrange a one-time expansion for some kind of "compressed" code, so we might still win in terms of both time and space complexity.
You can definitely apply strength-reduction to many of the calls to printf; to an extent compilers do this already.
I strongly recommend you take a look at cocinelle.
You will like its syntax, too.
CasperVector wrote:
I am interested in how you would respond to following opinion by the PL expert I mentioned previously, which was also a student of Dan Friedman.
"State-of-the-art compiler courses care very little about parsing; compiler optimisation, including code compression, instead of parsing, is the main subject of compiler techniques."
"Syntaxes of mainstream languages (including Haskell) make parsers hard to write and make the languages hard to transform, for really few benefits."
This is self-contradictory. First s/he pooh-poohs parsing(!) by saying no-one cares about it any more, then s/he says "parsing is hard", and the hand-wavey conclusion is "so let's change the language to make the parsing job easier":
CasperVector wrote:
"By using S-expressions, Lisp is easy to parse, and it is easy to implement code transforms from one well-defined 'language' into another well-defined 'language'."
That is simply a cop-out (and incorrectly implies LISP was designed to solve this "problem" no one else has.)

The reason there is nothing about parsers in "advanced" compiler courses, is because there is nothing more to be done; parsing is well-defined, and the theory and implementation both have been thoroughly worked-out in the 1970s.
Those discoveries are what forms the basis of any halfway-decent degree's "Core Computing 101".
So no, you don't tend to worry about it 10 or 20 years later; you were taught it at the start, and all your work since then has relied on its application.

Parsing is very much a "compiler technique", and it is essential. You just don't need to worry about it, since one can simply use yacc.
Further, the interesting "advanced" work in compilers is not so much about optimisation, as it is about "type theory" (a misnomer, but forgivable; all of this is simply application of Group Theory.)

In passing, I would just say that "change the input format" is a terrible cop-out for a computer-scientist of any description[1].
To be blunt: it is risible.

The whole of the above argument reads to me along the same lines as "shell is bad" (because I can't write it.)
"Parsing is hard" (no it's not: use yacc) so "change the input format" and condition the users to accept our much worse implementation (in fact it does not even fulfil the basic requirement, so it is a much worse impl of something not even requested), rather than admit we just don't know (how to use) the toolset and (here's the important part): learn it, already.
You're right: "worse is better", really is worse.

Should this cause any friction, please remind whomever that the well-defined transformative base is RPN, and if s/he doesn't know how to generate it from those "ill-defined" (pfft) inputs, then ffs get UPE. It's been part of the literature since the early 1980s, so there is zero excuse for such ignorance of fundamental research (or "prior Art" if you want to be academic about it), and indeed basic methodology (like tracking the literature to source.)

In any event, I would say: just get on and do it already. You already know lex and yacc, so set aside some money for books, and allow for at least a year or two of study if you're doing this part-time.
There is nothing to stop you, at all. All the tools are available for nothing, and all the literature is open to you.
You even have a head-start. ;-)

Just make sure to use IRC: chat.freenode.org or .net and check out #haskell if you're not already in there.
##posix and ##workingset when you want to actually get stuff done.
--

[1] I am not talking about reworking a grammar which already accepts arithmetic expressions, to keep it "context-free"; but about deciding that you know what, we just cba to parse actual expressions, because we mistakenly believe it to be difficult (and the cargo-cult tells us that's okay, really; "we can't write sh"^W^W "use yacc, either.")
The latter amounts to ignoring fundamental requirements decided upon before implementation was even conceived.
It is simply unacceptable.
Back to top
View user's profile Send private message
berferd
Tux's lil' helper
Tux's lil' helper


Joined: 13 May 2004
Posts: 87

PostPosted: Sat Jul 21, 2018 4:59 pm    Post subject: Reply with quote

Akkara wrote:
...Although I don't know what it says about a language if one needs to spend 6 months on an IRC channel before they are qualified enough to use it properly :)...


Sometimes the only way to win is not to play.
Back to top
View user's profile Send private message
steveL
Watchman
Watchman


Joined: 13 Sep 2006
Posts: 5122
Location: The Peanut Gallery

PostPosted: Fri Jul 27, 2018 10:52 pm    Post subject: Reply with quote

berferd wrote:
Sometimes the only way to win is not to play.
That's very true.
Unfortunately it has nothing whatsoever to do with learning a code language well enough to implement.
--
"Well enough" is in terms a programmer would use; not a "developer".
Back to top
View user's profile Send private message
pjp
Administrator
Administrator


Joined: 16 Apr 2002
Posts: 17345

PostPosted: Tue Aug 07, 2018 3:34 am    Post subject: Reply with quote

I split off the sociopolitical discussion per request.

[split] big companies, free software and unicorns.

I think I caught everything without taking too much. If not, let me know.
_________________
The whole system has to go. The modern criminal justice system is incompatible with Neuroscience. --Sapolsky
Back to top
View user's profile Send private message
steveL
Watchman
Watchman


Joined: 13 Sep 2006
Posts: 5122
Location: The Peanut Gallery

PostPosted: Sat Aug 18, 2018 7:44 am    Post subject: Reply with quote

pjp wrote:
I split off the sociopolitical discussion per request.

[split] big companies, free software and unicorns.
Thanks, pjp.
Love the title. :-)
steveL wrote:
I am not talking about reworking a grammar which already accepts arithmetic expressions, to keep it "context-free"; but about deciding that you know what, we just cba to parse actual expressions, because we mistakenly believe it to be difficult (and the cargo-cult tells us that's okay, really; "we can't write sh"^W^W "use yacc, either.")
The latter amounts to ignoring fundamental requirements decided upon before implementation was even conceived.
It is simply unacceptable.
Just wanted to follow up on this, as it's been pointed out to me, that it reads harshly, especially when one considers LISP's primary early usage for symbolic (mathematical) expressions, eg: of polynomial derivatives wrt x.

One part of me wants to leave it at "Turing complete" which is an old cop-out (since every Turing-complete language can emulate any other, at least in theory: practice is another matter.)

There is an insight here though, into why LISPers tend to avoid yacc (quite apart from many useful features being unnecessary, since LISP is at level 1 on the Chomsky ladder.)
LISP is essentially a language to write parsers with; whereas yacc gives you a language to specify the input (at symbolic level, or level 2; sufficient for all mathematical and arithmetic expressions), and obviates parsing code altogether. Both allow you to focus solely on what happens in response, and when.

Personally, I'm happier continuing to use yacc, where it is also simple to handle tokens at input level, before evaluation -- or we would not be able to code assignments (vs dereference.)
What LISP calls "symbols" we call "tokens"; a "tokseq" is a "symbolic expression", or a (LISP) list if you prefer (since it is really a superset: a code file is a seq of tok, as a file is a seq of chr.)

WRT code languages generally, good ones don't tend to change much at grammar level, and even less after the first 5 years of user-feedback and iteration: one thing time has shown, is that the core of a language should be small, not large.
I much prefer: foo(..) for function application, at grammar level too: IDENT LPAR is always a function (or functional form): much more obvious for the user, as it is in the grammar/for the context-free parser.

Still, it's no wonder that the LISPs are the best at macros, since they operate at token level, in linguistic terms.
--
So yes, the above is wrong on the conceptual level; however the point (where we started) is to have a language that compiles to asm. While LISP/FP may be a useful part of the pipeline, it is not the whole story; whereas C and yacc cover it all, and thereby your language can compile to asm, as well as your parser; your prototyping is much easier; and you are guaranteed to be able to convert it to a top-down parser any time you like, so long as you deal strictly with conflicts. (Nowadays, you don't even need to bother with that, if it's just multi-threading at parse-time that is your concern. info bison)
If speed concerns you, consider how fast awk has always been. (cf: usage in #bash ##workingset #awk.)
==
There's two overall aspects to my decision: firstly, I like being able simply to see what tokens and structures I am dealing with, in the source in front of me. While we can parse with a LISP, it's so much simpler in design to have the tokens laid out in front of me, in mnemonic form, and know precisely what they are (since we generated them in the first place.)
This is at the level of asm: where I feel most comfortable. This is the other aspect: remember, ALL of this is about computing on a digital machine.

You can only wrap, or automate, what you know.
There is no point in pretending you are wrapping something completely different, either; wrapping just enables you and others to think in a different manner.

I see no benefit in not dealing directly with C and asm, since that is what the CPU will see.
Binary operators are fundamental to asm, as they are to mathematics, so there is no mismatch. (I don't have to go down to level 1 in my thinking, when I am in asm: and it definitely has an inherent functional flow, so I lose nothing in terms of being able to apply modality.)

Further, yacc takes away the need for any of the code to check input validity (as I would need to do in a LISP: after all it's a language for writing what yacc does.)
This to me is similar to not having to worry about strings in sh, or the ability to use higher-order functions in a LISP; it takes away a level of worry from me, which the tool or runtime will deal with (using established theory. cf: the Dragon book.)

LISPs are much more useful in optimisation, and might have more place in automating yacc conversion to topdown parse, were it not already long-established prior Art; cf: Djikstra's "Shunting Yard" (code parsing and generation) and Wirth's "Compiler Construction" (generation of a topdown parser.)
Still, if I were 30 years younger and starting out, I'd definitely explore LISPs (SML is lovely, so are scheme and haskell); but I'd also make sure to learn about PROLOG (in addition to assembler and C, across architectures.)

If you're already into LISPs, consider how you would automate topdown conversion of a yacc parser from its (context-free) grammar rules.
And learn about PROLOG too, if you haven't used it already.

Just bear in mind: all you are ever producing is control-logic for a CPU.
Back to top
View user's profile Send private message
CasperVector
Tux's lil' helper
Tux's lil' helper


Joined: 03 Apr 2012
Posts: 94

PostPosted: Mon Sep 03, 2018 2:03 pm    Post subject: Reply with quote

steveL wrote:
There was none. Remember, LISP was conceived and implemented under even less resource.

But practical Lisp implementations were indeed more resource-demanding, due to characteristics like garbage collection and run-time type checking.
Before judging Lisp and C based on the resources available when they were respectively created, do note that Unix was born independent of C.

steveL wrote:
You are still conflating a portable assembler, a necessary first-step, with languages dependent on a userland running on top of the base provided by, and implemented in, that portable asm.
Until you make that distinction in your mind, and see where having that distinction leads, you will continue to muddle what is clear.

There seems to be zero reason that a portable assembly could not be expressed in a homoiconic form, eg. using S-expressions.
BTW, regarding bootstrapping, I find the GNU Mes project quite interesting.

steveL wrote:
Computing is not solely about computation: first and foremost, it is about the results. IOW: "side-effects" are the whole bloody point. (This comes up a lot with functional programmers.)
That is not to say that a LISP, or other language, cannot be used in implementation of the base; just that there is no real point, since it's already covered, and in a way that actually suits how we prefer to express ourselves.
(and without a load of self-styled "purists" complaining about all the "side-effects" everywhere.)

You seem to be again confusing Lisp with functional programming (i.e. excluding procedural programming etc.), which you then seem to confuse with purely functional programming (i.e. eliminating side effects at all costs).
Lisp is admittedly to a large extent based on lambda calculus, and does discourage side effects; however, it (at least Scheme) does not object to using another paradigm when the latter does significantly reduce the total complexity.
I suggest that you skim through The Little Schemer / The Seasoned Schemer and note how many times `!' occurs in the code before again identifying Lisp with functional programming.

steveL wrote:
That may well be, but I have just pointed out a contradiction between what you wrote above, and the reference you provided in support.
Without making a big deal about it, it behooves you to explain the contradiction, withdraw the remark, or otherwise explain the relevance of the reference or what you meant while conceding the reference does not support your statement.

On exactly the same page, Laurent does recommend using "type-specific formatting functions instead in production-quality code", which means buffer_puts() etc, so I see no contradiction at all.

steveL wrote:
While I agree with what he wrote there about only using one service for dnsproxy, I do not agree with him in not supporting "provides" (in openrc terms.)
It is not a disjunction; it is a set of alternatives, one of which must have been/be provided in some form or another, for the dependency to be fulfilled.
(Yes, I realise that a set of alternatives is a "disjunction" in propositional logic. This is not propositional logic.)
This is nothing radically new (it's effectively an "alias"); it dovetails quite easily into a dependency resolver.

I think Laurent intended to say that he does not want to implement disjunctions in the dependency resolution engine, but is fine with it implemented in an separate executable.
Which seems doable, although not yet implemented, perhaps because there are not enough people pushing Laurent people for the functionality.

steveL wrote:
I doubt this; the whole point of these little languages is that the code is already present, in the library function that handles the format, and the format encapsulates more work if we did it ourselves.
Your implementation cannot add less code than none at all. You can definitely apply strength-reduction to many of the calls to printf; to an extent compilers do this already.
I strongly recommend you take a look at cocinelle. You will like its syntax, too.

I want not to deny the presence of the code, but to discuss how the expansion of the format strings can be done better, in order to achieve optimal run-time complexity while keeping the source code clean.
Actually I know cocinelle, and think a lot of manpower could be saved when writing such static code analysis/transformation tools, had we used a homoiconic language in the first place.
On a deeper level, the latter is very consistent with "achieve optimal run-time complexity while keeping the source code clean": here "source code" refers to both the compilee and the compiler.
(Which is why the time consumption of a compiler's self-compilation matters, and hence the accolades for Chez Scheme, which self-compiles in seconds, and produces executables that sometimes outperform C.)

steveL wrote:
This is self-contradictory. First s/he pooh-poohs parsing(!) by saying no-one cares about it any more, then s/he says "parsing is hard", and the hand-wavey conclusion is "so let's change the language to make the parsing job easier".
That is simply a cop-out (and incorrectly implies LISP was designed to solve this "problem" no one else has.)

I find his logic to be "parsing is cost-ineffective, and therefore minimised in state-of-the-art compilers", so again no contradiction.
WRT ease of code transformations, I find this quite consistent with the goal of reducing the total complexity, which I think I have said quite a lot about.
And I do not think anyone who knows the history of Scheme would consider the statement as implying Lisp had been explicitly designed to ease code transformations:
https://en.wikipedia.org/wiki/Scheme_(programming_language)#Minimalism wrote:
In 1998 Sussman and Steele remarked that the minimalism of Scheme was not a conscious design goal, but rather the unintended outcome of the design process. "We were actually trying to build something complicated and discovered, serendipitously, that we had accidentally designed something that met all our goals but was much simpler than we had intended....we realized that the lambda calculus—a small, simple formalism—could serve as the core of a powerful and expressive programming language."


steveL wrote:
The reason there is nothing about parsers in "advanced" compiler courses, is because there is nothing more to be done; parsing is well-defined, and the theory and implementation both have been thoroughly worked-out in the 1970s.
Those discoveries are what forms the basis of any halfway-decent degree's "Core Computing 101".
So no, you don't tend to worry about it 10 or 20 years later; you were taught it at the start, and all your work since then has relied on its application.

As stated above, the reason is surely not "there is nothing more to be done"; moreover, even the "reason" itself is not true to begin with, for instance cf. PEG.

steveL wrote:
Parsing is very much a "compiler technique", and it is essential. You just don't need to worry about it, since one can simply use yacc.
Further, the interesting "advanced" work in compilers is not so much about optimisation, as it is about "type theory" (a misnomer, but forgivable; all of this is simply application of Group Theory.)

Judging from the SLOCs (or more fundamentally, Kolmogorov complexity), the interesting parts in compilers are surely very much about optimisation.
Actually, I think quite a few compiler tecnhiques are not trivial corollaries of type theory; call it "applied type theory" if you want, but then I would not just call compilers tecnhiques "about type theory".
And BTW, type theory turns out to be roughly on the same level of category theory, which is roughly on the same level of set theory; in comparison, group theory is a part of algebra, which is usually based upon set theory.

steveL wrote:
In passing, I would just say that "change the input format" is a terrible cop-out for a computer-scientist of any description. To be blunt: it is risible.
The whole of the above argument reads to me along the same lines as "shell is bad" (because I can't write it.)

Sorry, but I find your analogy unfortunately like "Bach did not write operas because he was incapable of writing them" (as demonstrated in Schweigt stille, plaudert nicht, he clearly could).
The person I repeatedly referred to wrote this post (sorry, I do not want to translate it in its entirety), which I think proves that he is perfectly able to write decent parsers.
(That person is highly controversial in my circle; frankly, I find him too radical in expression. These however do not falsify quite a few technical points he makes.)
_________________
My current OpenPGP key:
RSA4096/0x227E8CAAB7AA186C (expires: 2020.10.19)
7077 7781 B859 5166 AE07 0286 227E 8CAA B7AA 186C


Last edited by CasperVector on Wed Sep 05, 2018 2:35 am; edited 14 times in total
Back to top
View user's profile Send private message
CasperVector
Tux's lil' helper
Tux's lil' helper


Joined: 03 Apr 2012
Posts: 94

PostPosted: Mon Sep 03, 2018 2:36 pm    Post subject: Reply with quote

steveL wrote:
There's two overall aspects to my decision: firstly, I like being able simply to see what tokens and structures I am dealing with, in the source in front of me. While we can parse with a LISP, it's so much simpler in design to have the tokens laid out in front of me, in mnemonic form, and know precisely what they are (since we generated them in the first place.)

After all, the syntax is a UI, and the choice of a UI is a "religious" problem, so I do not want to convince you that you should use a homoiconic language.
However, you seemingly still do not object to the original motivation of what I pursue: a homoiconic linguistic basis for most practical aspects of programming, which dramatically reduces the total complexity of the system.
I said it, and now say it once more: I guess reconciling Lisp and Unix would be much easier than reconciling quantum mechanics and general relativity; and it would be, in a perhaps exaggerated sense, as meaningful.

steveL wrote:
Further, yacc takes away the need for any of the code to check input validity (as I would need to do in a LISP: after all it's a language for writing what yacc does.)
This to me is similar to not having to worry about strings in sh, or the ability to use higher-order functions in a LISP; it takes away a level of worry from me, which the tool or runtime will deal with (using established theory. cf: the Dragon book.)

On the contrary, I find Lisp to be like what yacc produces, as ASTs can be trivially represented as S-expressions.
(Hence the saying that it facilitates code transformations from one well-defined "language" into another well-defined "language".)

[Following are replies to parts of some older posts, and are mostly clarification of relevant concepts:]
steveL wrote:
I know what you mean about hygienic macros. But really, this is just about correctly stacking (or scoping) during eval.

Actually, this is not about hygienic macros, but about structural macros: with the latter, hygiene can be enforced in multiple ways; without the latter, you would lose a lot.
eg. Makefile or the shell can be emulated in Lisp using macros, and a possibly unprecedentedly powerful type system can be constructed.
The same is definitely impossible in C, or otherwise C++ would not even have existed.

steveL wrote:
I am not saying "show us the code" blah blah; I am saying: Show us what you mean, in a yacc grammar file.

Now I guess you have realised that what I want is completely independent of parsing, and that a `.y' file is therefore definitely not my goal. Instead, I currently have two ideas:
* Introduce gradual typing into Scheme, in a way like that with Typed Racket; and study how features like garbage collection could be optimised out by the compiler.
* Since C is a portable assembly, perhaps I can learn from Chez Scheme's own assembler; semi-low-level code generators like DJB's qhasm might also be a good reference.
In any case, I would need to learn much more about PL theory, and let's see what will happen.
_________________
My current OpenPGP key:
RSA4096/0x227E8CAAB7AA186C (expires: 2020.10.19)
7077 7781 B859 5166 AE07 0286 227E 8CAA B7AA 186C
Back to top
View user's profile Send private message
steveL
Watchman
Watchman


Joined: 13 Sep 2006
Posts: 5122
Location: The Peanut Gallery

PostPosted: Wed Sep 19, 2018 5:42 am    Post subject: Reply with quote

steveL wrote:
There was none. Remember, LISP was conceived and implemented under even less resource.
CasperVector wrote:
But practical Lisp implementations were indeed more resource-demanding, due to characteristics like garbage collection and run-time type checking.
Before judging Lisp and C based on the resources available when they were respectively created, do note that Unix was born independent of C.
Eh, what now?
A) Who has been judging LISP and C based on resource? I certainly haven't. Have you?
So why slip that in there?
B) UNIX was not "born independent of C". I thought we'd established that ages ago.
In the same vein, it was developed alongside and including SH, which has always been a central part of the design (or at least some sort of shell.)

I am sorry but the rest seems to me to be along the same lines, wherein you backtrack on understanding we had already agreed upon (all of it pretty basic.)

I will come back to it when I am not quite so ragged from long hours of work, which perhaps is clouding my reaction.

I do find the pages you have linked interesting, such as GNU mes, and the one on Type Theory, linking to category theory. Much of what I have read in linked pages, makes me want to comment about the laxity of the whole "modern" approach; but I am not sure that would be very useful at this juncture.

I think much of the problem stems from mono-lingual people who have zero clue about other ways of thinking, or even that they exist at all.
That these same people are mono-lingual in English, the most dumbed-down language of all, makes it much harder to get through.
Back to top
View user's profile Send private message
CasperVector
Tux's lil' helper
Tux's lil' helper


Joined: 03 Apr 2012
Posts: 94

PostPosted: Wed Sep 19, 2018 8:35 am    Post subject: Reply with quote

steveL wrote:
A) Who has been judging LISP and C based on resource? I certainly haven't. Have you?

You were attempting to refute "we should also reconsider the restrictions put by these [resource] limits on ...", based on the resources available when Lisp was "conceived and implemented".
Admittedly it was me that was judging LISP and C based on resources, but you were attempting to find an inconsistency in my argument.
... which was based on practical implementations of C and Lisp, so the focus in the following sentence was not "resources available", but "when they were respectively created":
CasperVector wrote:
Before judging Lisp and C based on the resources available when they were respectively created, do note that Unix was born independent of C.


steveL wrote:
B) UNIX was not "born independent of C". I thought we'd established that ages ago.
In the same vein, it was developed alongside and including SH, which has always been a central part of the design (or at least some sort of shell.)

From my understanding, their link in development mostly formed when Unix was being ported to PDP-11, instead of when it was born.
Noticed the (roughly) similar relations between "born" vs "ported" and "conceived and implemented" vs "practical implementations"? Hence the analogy.
(The time spans for the two relations are surely quite different, but they to some extent do reflect the development of fundamental features in the two software systems.)

steveL wrote:
I am sorry but the rest seems to me to be along the same lines, wherein you backtrack on understanding we had already agreed upon (all of it pretty basic.) [...]
Much of what I have read in linked pages, makes me want to comment about the laxity of the whole "modern" approach; but I am not sure that would be very useful at this juncture.

I look forward to seeing a few examples which you consider representative.

steveL wrote:
I think much of the problem stems from mono-lingual people who have zero clue about other ways of thinking, or even that they exist at all.
That these same people are mono-lingual in English, the most dumbed-down language of all, makes it much harder to get through.

Just in case, perhaps except for Laurent, the people involved in my posts (PL researchers, the Dale folks, me, etc) are surely not monolingual in the PL sense.
And since Laurent is French and the skarnet mailing lists are in English, he is definitely not monolingual in the natural language sense.
_________________
My current OpenPGP key:
RSA4096/0x227E8CAAB7AA186C (expires: 2020.10.19)
7077 7781 B859 5166 AE07 0286 227E 8CAA B7AA 186C
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Gentoo Chat All times are GMT
Goto page Previous  1, 2
Page 2 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum