There are many languages I’d rather use than Lua, which is basically a rather broken and limited rewrite of Python.

they’re not related at all :blobcattableflip:

@shadowferret @sjw @icedquinn Whoever wrote that, I'll fight that guy. Python and Lua are not even sort of similar in terms of design, goals, etc., but I'm not sure what he means by "broken" and it's also misguided to think of scope limitations are inherently bad.

:dmr: A language that doesn't have everything is actually easier to program in than some that do. :dmr:

awk is one of the most limited languages I've used, but it's also one of the most useful.
@p @shadowferret @icedquinn @sjw

> awk is one of the most limited languages I've used, but it's also one of the most useful.

I'm still working on my magnum opus that will stick it to all the `awk` fanboys. Masochistic Unix weenies please follow.
@petit @icedquinn @shadowferret @sjw I think it's hard to beat awk.

You've probably seen this, or maybe not, but :bwk: gave a really interesting lecture: https://www.youtube.com/watch?v=Sg4U4r_AgJU
@p @icedquinn @shadowferret @sjw

I have not seen it, but went ahead and watched it.

It's always weird hearing language design advice from people who don't know anything about lisp. Writing an Awk DSL in Lisp would be a lazy afternoon.

(Actually working on one now.)

;; Example
(with-open-file (stream "food.txt")
(let ((accum (make-hash-table :test #'equal)))
(funcall (awk-rules (":")
(START ((format t "Starting Report~%")))
((incf (gethash $1 accum) $2))
(END ((loop for key being each hash-key in accum
do (format t "~a:~a~%" key (gethash key accum))))))
stream)))

(defmacro inject-field-symbols ((line seperator) &body body)
(let ((count 0)
(field-symbol (gensym "FIELD-")))
`(let ((field-symbol (cl-ppcre:split ,seperator ,line)))
(symbol-macrolet ,(loop for item in field-symbol
collect `(,(intern (concatenate 'string "$" (format nil "~a" count))) ,item)
do (incf count))
,@body))))


(defmacro awk-rules ((seperator) &body body)
(let ((rules (make-hash-table :test #'equal))
(line-symbol (gensym "LINE-"))
(file-symbol (gensym "FILE-")))
(loop for rule in body
do (cond ((and (listp rule) (= (length rule) 2))
(setf (gethash (first rule) rules) (second rule)))
((and (listp rule) (= (length rule) 1))
(setf (gethash ".*" rules) (first rule)))
(t (error (format nil "Invalid rule format ~a" rule)))))
`(lambda (,file-symbol)
(loop for ,line-symbol = (read-line ,file-symbol nil)
while ,line-symbol
do (inject-field-symbols (,line-symbol ,seperator)
,@(gethash 'start rules)
,@(loop for pattern being each hash-key in rules
when (not (member pattern '(start end)))
collect `(when (cl-ppcre:scan ,pattern ,line-symbol)
,(gethash pattern rules)))
,@(gethash 'end rules))))))

(I need to figure out a better way to generate the $0, $1, $2, etc. bindings and fix up the input format, but it's not too much effort to make something comparable. I can add reader macros and get something even cleaner.)

I also hate hearing the scripting/programming language dichotomy. Credit to Kernighan for qualifying the distinction, but I'm still annoyed.

67. Think of all the psychic energy expended in seeking a fundamental distinction between "algorithm" and "program". -Alan Perlis, Epigrams on Programming

Think of all the psychic energy expended in seeking a fundamental distinction between "scripting" and "programming". -Petit, Mastadon Network

I definitely agree with the part about trying to leverage an existing ecosystem. Look at all the JVM languages.
@p @icedquinn @shadowferret @sjw

But really, writing Awk in Lisp sort of misses the point. Yes, it would be extremely fast (my money is on faster than C) since you're generating assembly instead of simulating a table of rules. Yes, you could make the syntax whatever you want. Yes, the implementation would be very short.

The high level language freaks don't care about tools like sed or awk, because they live in their favorite language's interpreter, not a shell. Awk is way faster than writing a Python script, unless you already have Python open.
@petit @icedquinn @shadowferret @sjw

> The high level language freaks don't care about tools like sed or awk, because they live in their favorite language's interpreter, not a shell.

Yeah, that's the thing, it's the difference between being able to reach for anything and focusing on one thing. I think it's nicer to be able to connect things, monolithic systems are brittle. (On the other hand, extremely connected things are unreliable.)
@p @icedquinn @shadowferret @sjw

>Yeah, that's the thing, it's the difference between being able to reach for anything and focusing on one thing. I think it's nicer to be able to connect things, monolithic systems are brittle. (On the other hand, extremely connected things are unreliable.)

A theme for me: The only difference between monolithic and unconnected software is convention.

Many assume that the standard model for computing is binaries the loader can understand, that accept stringly typed command line options to start, and communicate over STDIN, STDOUT, and STDERR.

But this is all arbitrary convention.

Looking closer, most Unix programs are really just functions returning via STDOUT.

Looking closer, features taken for granted today are echoes of batch programming.

People dismiss the Lisp world because they want something that fits with their existing world, which is fine. The problem is people lapsing from "existing world" to "actual world". Nothing about pipes, virtual memory, arguments, and portable binaries is necessarily necessary or even good.

The most frustrating part of all this is people reject the Unix world in other domains. Programming languages do *not* work like Unix. Subroutines communicate by passing typed arguments, not pipes or string arrays. Almost every programming language has almost the same procedure calling system, but people insist on argc and argv as the standard.

(I know this critique isn't Unix specific, but I don't care enough to define a better target.)

/rant
@petit @icedquinn @shadowferret @sjw

> The problem is people lapsing from "existing world" to "actual world". Nothing about pipes, virtual memory, arguments, and portable binaries is necessarily necessary or even good.

Well, how do you talk to the outside world? TCP packets make a stream, disks pretend to be big, contiguous wads of unformed bytes, files sit on the disk masquerading as contiguous bytestreams, processes spew bytestreams. You've got to be able to speak lowest-common-denominator to get anything into or out of your program, and lowest-common-denominator is ordered bits.

In these big companies, there are systems where you control both ends of the pipe, so you see them standardize on almost-REST JSON or ProtoBuf or SOAP¹, but there's an entry point into the system where things inexpressible within the system are received by the system and converted (with some friction) into some form acceptable to the system. There will always exist data that the system can't express. What's above this, what's the generalization of these systems?

I forget who was saying this, but I was listening to some lecture and the guy said that he got irritated when people talked about natural selection creating change, because it's the opposite: natural selection preserves the necessary characteristics. If something changes, it's because that thing didn't matter. What do you get if you try to apply this to operating systems?

So Unix doesn't clamp down enforcing structure and you can express whatever, you can fit a structured system into it, using its building blocks. Structure is an assertion: this matters enough that it will not need change. Unix isn't a system the way Lisp is a system, you decide too many things when building something on top of Unix. Unix is more like the subset of features all systems have. I realized this some time into playing with Plan 9, and I was frustrated a while, it felt half-finished in some regards, and I'm sort of passively absorbing the approach by reading man pages from Bell Labs, I'm reading stuff by people that built things on top of Plan 9, watching the mailing list and people are saying "You can make this with this", stuff like that, and something eventually leaps out at me while talking to a friend about this, something they never seem to make explicit because we're all talking past each other: Plan 9 isn't an operating system, it's a pile of building blocks. You look at old Unix stuff, you can see it there, too. It's not a product, it's not built that way, it's not really an operating system. Look at Plan 9's cat, look at GNU's. The GNU system was an attempt to build an operating system rather than "This is stuff you can use to build the system you want". "cat came back from Berkeley waving flags" looked like a crazy thing to say to people from the outside, but if you think of Unix as something for building systems rather than the end-goal, the system you want, then it clicks why BSD felt wrong to the Bell Labs guys, and if you think about the nature of the misunderstanding itself, then it clicks why nobody really cared. BSD was an operating system, that's what they were doing. Linux and HURD are operating systems. Unix as designed is not.

Anyway, "Unix is not an operating system" is my $0.02 on the matter, YMMV, you have no real way of knowing that I'm not some kind of lunatic.

¹ How this usually *actually* plays out is that several years-long attempts to standardize on something result in several subsystems where the legacy thing is spewing XML and the new one speaks almost-REST, you've got multiple backends with something in front of it that talks to all of them except sometimes it talks to the DB directly, and then *that* system ends up behind *another* system.
Follow

@p @icedquinn @sjw @petit @shadowferret 10/10 would understand 40% again

· · SubwayTooter · 0 · 0 · 1
Sign in to participate in the conversation
Qoto Mastodon

QOTO: Question Others to Teach Ourselves
An inclusive, Academic Freedom, instance
All cultures welcome.
Hate speech and harassment strictly forbidden.