250 points aragonite 3 days ago 102 comments
TheSilva 1 day ago | parent
Object.prototype.message='alert\x281337\x29';Array.prototype.toString=Error.prototype.toString;Error.prepareStackTrace = Function;const x = new Error;x.valueOf=x.stack;+x;
Well, that's a mouthful! So many years and JavaScript still can do the most amazing, weird, awesome, scary, obscure, and sexy things in the world of coding.customguy 23 hours ago | parent
(function () {/*
my awesome shader code
*/}).toString().match(/[^]*\/\*([^]*)\*\/\}$/)[1]
... I can't call it sexy, but I also can't deny I felt a mixture of fear and arousal when I saw that.h43z 22 hours ago | parent
(x=>/*this is a comment*/1) + 1
"x=>/*this is a comment*/11"
I wonder if anything cool can be done with it today. It's probably useless.annex-winged-cr 22 hours ago | parent
gmac 22 hours ago | parent
chii 21 hours ago | parent
fg137 23 hours ago | parent
semiquaver 1 day ago | parent
user____name 23 hours ago | parent
toolslive 21 hours ago | parent
hk__2 20 hours ago | parent
marcosdumay 18 hours ago | parent
The sooner that abomination is killed, the best.
NetMageSCW 16 hours ago | parent
diegof79 14 hours ago | parent
Honestly, I can point you to languages with worse design than JS.
There was an idea (perhaps from BASIC) that "scripting" means permissive. Instead of failing fast, it was designed to fall back to something that works (e.g., '1'+1=2). That's a terrible design decision, and JS tried to reverse it in every future iteration.
The other two big issues for me were: trying to imitate Java (with the new keyword, instanceof, and null). The prototype mechanism that JS took from Self is simpler and easier to understand if you leave out those constructs.
The other issue was the lack of modules. That was part of the idea that JS was for short, interactive scripts on a page; the initial version didn't plan for how we use it today.
Other than that, I prefer JS over Perl, C, C++, PHP, shell scripting, or TCL.
Edit: Actually, '1'+1 is '11' in JS (facepalm), but '1'*2 converts to a number. That's why it was a terrible idea. But, to be fair, many "scripting" languages did that kind of type coercion. I guess that language designer hated cryptic compile errors.
aktenlage 1 day ago | parent
hans_castorp 1 day ago | parent
> We stopped when we got a clean compile on the following syntax:
for(;P("\n"),R--;P("|"))for(e=C;e--;P("_"+(*u++/8)%2))P("| "+(*u/4)%2);nathell 23 hours ago | parent
‘Larry, throw the cat at the keyboard!’
MEEEOW!
‘What did it type?’
‘&}Ak'>v=4%Qe}9;’
‘OK, so let’s make this a syntax for hello world.’
saghm 22 hours ago | parent
nullsanity 22 hours ago | parent
Bareword found where operator expected (Missing operator before "Ak"?) at -e line 1, near "&}Ak" Bad name after Ak' at -e line 1.
1718627440 20 hours ago | parent
bjoli 22 hours ago | parent
I haven't seen it in many many years, but at the time it struck my giggle button every time.
shevy-java 19 hours ago | parent
shawabawa3 19 hours ago | parent
here's an actual one: print'(%,,/@(/),$!'^'`@@@@`_@[@@+'
another one
$/=~s##'&}(/%]?`~=.&~(@^,_!$/"'^'+.{|}!_{.|=.^_/,@;'^'}!:=,^(~<-|$'#eemarcosdumay 19 hours ago | parent
akavel 20 hours ago | parent
a4isms 20 hours ago | parent
Great guy to work with. I think he runs a craft brewery now.
lifthrasiir 19 hours ago | parent
DonHopkins 20 hours ago | parent
https://donhopkins.com/home/catalog/unix-haters/etc/unix-is-...
nathell 1 day ago | parent
stymaar 22 hours ago | parent
That will also serves as a litmus test to check how many of my coworkers are reading the code they push.
kpcyrd 20 hours ago | parent
amelius 22 hours ago | parent
(((x)f)g)h
So I can see exactly the order in which things happen, from left to right.
As opposed to: f(g(h(x)))
where I have to read backwards.danlitt 22 hours ago | parent
since the order in which things happen is "h first, then g, then f"
ktpsns 22 hours ago | parent
layer8 21 hours ago | parent
account42 21 hours ago | parent
Rohansi 21 hours ago | parent
foo.bar(x)
The `foo.bar` field has to be retrieved before the function can be called. It does not evaluate `x` first. That is observable with JS proxies, or you can test with code like this: foo()(bar())LtWorf 21 hours ago | parent
Rohansi 20 hours ago | parent
But my point is that the reference to the function you are calling is actually its own term that needs to be considered in the order of evaluation.
You can also use the IIFE (immediately invoked function expression) pattern that is/was common in JS as an example:
(function() {
// ...
})();
You can use any valid expression in place of a function name, including anything that causes observable side effects.LtWorf 19 hours ago | parent
raverbashing 21 hours ago | parent
It's more natural to write
x.h().g().f()nine_k 21 hours ago | parent
As to more serious programming languages, Erlang, F#, Haskell have forms of a "pipe" operator, roughly
[1 2 3] |> sum |> print
For it to work properly, functions should be either functions of one argument, or support currying.But the original algebra functions, as introduced by Leibniz in 17th century, were, of course, pure functions, more like properties than procedures. So cos(x), aka cos x, is just a formalized shorthand for "cosine of x", so it preserved the order of words typical for Germanic and Romance languages. Maybe if functions were introduced by the Japanese, we would have the reverse order, kind of x の cos.
rafaelRiv 20 hours ago | parent
adverbly 21 hours ago | parent
When you're calling a function, you're putting some things into the function... You have to get the things first before you can put them in...
Why didn't it evolve like that in the first place? Is it a byproduct of mathematical notation? If so, I wonder why mathematical notation evolved that way in the first place...
stronglikedan 21 hours ago | parent
It did, just in Arabic.
baruchel 21 hours ago | parent
arethuza 20 hours ago | parent
ashkankiani 21 hours ago | parent
But you can also define a "thread" operator easily for doing subsequent function calls. ala `threaded x { f; g; h }`
skocznymroczny 21 hours ago | parent
f(g(h(x))) as x.h().g().f() or even x.h.g.f (parenthesis are optional).
anal_reactor 21 hours ago | parent
u v x y
f g
h
This is h(f(u,v), g(x,y)).amavect 17 hours ago | parent
│u│v│x│y
├─┴─├─┴─
│f │g
├───┴─
│h
└─
With >2 inputs and longer names. │uh│v │xizzy│yeez
├──┴─ ├─────┴────
│fooey │gar
├──────┴───
│hello
└─────
The associative property. (a+b)+c=a+(b+c)=a+b+c
│a│b │b│c
├─┴─ ├─┴─
│+ │c│a│+ │a│b│c
├───┴─├─┴─ ├─┴─┴─
│+ │+ │+
├─────┴─────┴─
│=
└─
The quadratic formula. (-b±sqrt(b^2-4*a*c))/(2*a)
│b│2│4│a│c
├─┴─├─┴─┴─
│^ │*
├───┴─
│b│-
├─├─
│-│sqrt│2│a
├─┴────├─┴─
│± │*
├──────┴─
│/
└─
Obviously, it takes way more space and time to draw. Tell me if you like it!mesrik 20 hours ago | parent
So is this better too
$ less | find / -type f -perm /6000 -ls
than ? $ find / -type f -perm /6000 -ls | less
Just because shell actually starts executables right to left when using pipes.
Reason to this behaviour is because it can fail early if there is problem constructing pipe first and not spend lot of time something finding later that some pipe components can't start and receive data properly.ps. I'm fine with current notation and would not like change it.
unilynx 19 hours ago | parent
f3(f2(f1(some data)))
it would be nice to write some data |> f1 |> f2 |> f3
javascript has proposals for pipe operators because as soon as the simple .map /.filter/.reduce APIs don't suffice (ie. as soon as Promise.all is needed) the f3(f2(f1(data))) mess starts.kiicia 20 hours ago | parent
var chain = x=>f=>f?chain(f(x)):x;
chain(x)(h)(g)(f)();
if you need to partly curry to free first argument var _ = (f,...y)=>x=>f(x,...y);
var sum = (x,y)=>x+y;
chain(1)(_(sum,1))()
if you want whole pipeline var $ = (x,...f)=>f.reduce((x,f)=>f(x),x);
$(1,_(sum,1));
which gives fun ability to extract function without input param var sum1 = _($,_(sum,1));
sum1(1);
... which in turn is just having fun with point-free JSbunderbunder 19 hours ago | parent
x
|> f
|> g
|> h
It's nice because it just puts whatever's on the left of the operator in as the last argument. So it also works for functions with an arity of more than one.So if it were something like
h(z, g(y, f(x))
you can write it as x
|> f
|> g y
|> h z
It works really nicely for data munging code: my_data
|> filter (x => x > 37)
|> select (x => x * 2)
|> sum
but unlike doing it with method calls in object oriented code, inserting a new function into the chain doesn't involve modifying a class or or mucking around with more complex language features like extension methods and traits.pfdietz 19 hours ago | parent
bunderbunder 19 hours ago | parent
pfdietz 17 hours ago | parent
tomsmeding 19 hours ago | parent
FuckButtons 15 hours ago | parent
sparkie 33 minutes ago | parent
(h . g . f) x
Or for LtR, with Control.Category (f >>> g >>> h) x
Could combine with the forward pipe for x |> (f >>> g >>> h)taolson 18 hours ago | parent
MattCruikshank 21 hours ago | parent
Global variable.
Parameter to a function.
Pass a functor/lambda, get the value.
Environment variable.
Registry.
File.
Store it in a ping response.
VRAM texture that you write and then read.
Database.
REST server.
I'm pretty sure I could come up with a thousand ways.
But... why? Why do I want to write this book? Why has it been on my mind?
CoastalCoder 20 hours ago | parent
It's very compiler-focused, but it's one piece of the puzzle.
arethuza 20 hours ago | parent
fwip 20 hours ago | parent
MattCruikshank 18 hours ago | parent
You have the camera... I have the monitor... How about I flash QR codes? Oh, the camera is on top of the monitor, facing the room? Well, at night, I could FLASH the monitor full white in binary, and you can see the light on the chair and wall, right?
I'll leave the disc head on the sector number. You read the disc head position.
I'll exit my function on a time modulo a number to encode the remainder. You see what time you were called, and can decode the remainder.
I'll warm the CPU to a temperature... you read the temperature...
The list goes on and on...
"The Exfiltration Manual"...?
vvill 19 hours ago | parent
And something my friend wrote a few years ago: https://github.com/radian628/tram
Data storage and transmission has so much innovation going on!
shevy-java 20 hours ago | parent
(Though, parentheses are sometimes needed due to ambiguity. But by and large, the lispy legacy has been overcome already.)
jlhawn 17 hours ago | parent
> \x28
> \x29
does this not count as using parentheses?
airtnp 17 hours ago | parent
sharktheone 17 hours ago | parent