<Armael>
it's a arena-like region with very fast (bump-pointer) allocation
<olle_>
ok, no idea if php uses such a thing or not :d
<olle_>
anyway
<companion_cube>
probably not; as you said it's just refcounting (over malloc, most likely)
<olle_>
I was thinking immutability is seen like a silver bullet, and that the discussion should take into account other tools like ownership/uniqueness
<companion_cube>
I doubt that php is good at immutability
<olle_>
companion_cube: mm
<companion_cube>
ownership is very new (in type systems)
<olle_>
companion_cube: yet immutability is pushed as a solution, even part of some PSR standards
<olle_>
companion_cube: what about clean lang?
<Armael>
the point being that allocating short lived data is cheap, because allocating it in the minor heap is cheap , and then it is usually dead when the minor heap is full and needs to be collected
<companion_cube>
olle_: a research project, I think?
<olle_>
companion_cube: sure, but they have opt-in uniqueness :)
<companion_cube>
in the grand scheme of things, even pattern matching and sum types are barely adopted
<olle_>
like ocaml's ref, but with uniqueness constraint.
<companion_cube>
(PSR?)
<olle_>
PSR is a standard family in PHP, for APIs, syntax style, etc
<companion_cube>
yeah well you need a special typechecker for that
<olle_>
companion_cube: isn't escape analysis enough? if the variable escapes, you violate uniqueness.
<companion_cube>
escape analysis is generally not entirely accurate, is it?!
<olle_>
Armael: OK, sounds true for tracing GC :)
<companion_cube>
just an optimization heuristic
<olle_>
eh, dunno :|
<olle>
would affine types solve the same problems as uniqueness?
<companion_cube>
php is getting neither, get real
<olle>
companion_cube: I was thinking of ocaml xD
<olle>
I could possibly implement some simple non-aliasing checking for Psalm...
<olle>
Psalm already has immutable, readonly, pure, and stuff like that.
<olle>
so they're definitely ripping off functional languages :)
mro- has joined #ocaml
amiloradovsky has quit [Remote host closed the connection]
<Drup>
from an optim point of view, uniqueness/ownership/linearity are the same as an interprocedural pessimistic aliasing analysis
<Drup>
so, whenever you can use aliasing analysis, you'll get the same benefits
<Drup>
in general programming languages, it's really hard to fully benefits from those things. It works in slightly more constrained settings
<Drup>
ocaml doesn't have that kind of optims because its optimisations are mostly type-oblivious. Also, with linearity, type abstraction can be used to disguise mutable objects as immutable, which sorts of "bake in" the optimisation manually
raver has quit [Quit: Gateway shutdown]
<olle>
Drup: hey, thanks drup!
* olle
writes it down
<olle>
Drup: sooo, what's more reasonable: port clean's uniqueness system to ocaml, or solve it with affine/linear types?
raver has joined #ocaml
<olle>
wait, you said above already
<olle>
although I don't get how the combination linear + type abstraction works
<olle>
I should read more about how Clean did it, I think.
<Drup>
eh, Affe is clearly a superior system compared to clean :<
<olle>
Drup: well
<olle>
it must be usable by normal people too
<Drup>
Affe's probably more usable, if only because of borrows
<Drup>
(but that first comment was /s, just in case)
<olle>
Wait, you're the author ^^
<olle>
I was thinking of a type-check to annotate classes as "no-alias", and then you have to clone them if you want to pass them on (no borrower)
<Drup>
yeah, linear-logic style. It's horrible to program with. David Walker's chapter in ATTAPL is already better than that.
<olle_>
Drup: horrible?
<olle_>
it's mutable, with no aliasing
<olle_>
so mutable + unique with no borrower
<olle_>
opt-in unique, btw
<Drup>
you need to adopt a purely-functional state-passing style for all of your functions that are not methods of the object
<Drup>
I've seen systems like that, they are "simple" in the way Go is: you compensate your system lack of flexibility by imposing huge tedium on programmers
<Drup>
it kinda works, I guess, the same way you can drive a nail with your head. I'm not a fan. :p
<Drup>
linearity+object is kinda tricky, I must admit I haven't looked so deeply into it. There are several very complicated system, or super simple ones like what you described, but not much in between
<Drup>
(at least as far as I know .... maybe there is something to do there ...)
mro has joined #ocaml
mro has quit [Client Quit]
mro- has joined #ocaml
mro- has quit [Client Quit]
Jeanne-Kamikaze has quit [Quit: Leaving]
<olle>
That doesn't sound like what I'm looking for
<olle>
Example
<olle>
$q = new Query(); $q->select = '1'; $q->from('table');
<olle>
And then
<olle>
myfun($query); // Invalid
<olle>
myfun(clone $query); // Valid
<olle>
Mutable object that's not allowed to escape.
<Drup>
ah, so that's not linearity you want, it's escape analysis
<olle>
Non-aliasing
<olle>
Not "consume once"
<Drup>
You might be interested in the paper "Gentrification gone too far"
<Drup>
(yes, that title is weird, I love it)
<Armael>
hah, I read that one
<Armael>
because something something capabilities
<Drup>
Affe's ownership stuff is greatly inspired by it
<olle>
hm
<Drup>
olle: althoug, at the end of the day, what you want is very simple to implement: just decide that all non-alias objects are passed by copy :]
<Drup>
you don't even need a type system for that.
<olle>
Drup: then I'd have to dig into the php source code
<Drup>
well, you can auto-inser the call to `clone` on each callsite.
<olle>
but no, i want to be able to *enforce* non-aliasing, not automatically adapt
<olle>
or do i?
<olle>
php actually had value semantics for objects back in the day
<Drup>
(Rust does something similar, it auto-copy/clone when appropriate)
<olle>
so they always copied
<olle>
yeah?
narimiran has quit [Ping timeout: 256 seconds]
<companion_cube>
there's a trait named `Copy` for such value types, yes
<companion_cube>
makes it bearable to use integers
<olle>
companion_cube: in php?
<olle>
oooh, rust ^^
tryte has quit [Read error: Connection reset by peer]
tryte has joined #ocaml
<olle>
waaait
<olle>
does ocaml remove dead code?
<olle>
when compiling
<olle>
my mutable example is slower than my immutable one
<companion_cube>
which dead code?
<olle>
companion_cube: unused variable
<companion_cube>
well if it's assigned to a non-trivial expression, it could have side effects
<olle>
companion_cube: it's just a record
<olle>
q = {select = "1"}
<companion_cube>
ah! and what do you expect ocaml to do?
<olle>
companion_cube: I want to compare the performance between using {record with field = "bla"} vs record.field <- "bla"
<olle>
(same as I just did in PHP)
<companion_cube>
first, be careful how you measure; second, writes in OCaml have a write barrier
<olle>
when running with `time`, it looks like ocaml just removed all variables that were not used
olle_ has quit [Ping timeout: 240 seconds]
<companion_cube>
maybe? look at `-dlambda` or sth like that I guess
amiloradovsky has joined #ocaml
<olle>
hm, looks like something is happening
<olle>
but doesn't make sense
<olle>
why would immutable record be much faster than mutable?
<olle>
gah
Serpent7776 has quit [Quit: leaving]
<olle>
it's 5x slower to use mutable fields
<olle>
I can post it on the forum, maybe I messed up
<Armael>
I'm not an expert of reading cmm code, but if you run the compiler with -dcmm it looks like all the record creation is optimized out in the pure case
<Armael>
I might be wrong tho
<olle>
Let me check
<olle>
Armael: Yep, looks like it
<olle>
T_T
<olle>
Even when I end the loop with the variable
<companion_cube>
loops do not return any value but ()
<Armael>
meaningful synthetic microbenchmarks are hard to do
<olle>
:d
<sadiq>
olle: it's because of the write barrier
<sadiq>
oh someone's already mentioned that
<olle>
sadiq: I thought that was a GC thing? e.g. runtime, not compilation
<olle>
i.e.*
<companion_cube>
well you're measuring the runtime
<olle>
I'm reading the cmm code (whatever that is...)
<Armael>
the write barrier is something different from having your benchmark code optimized out
<sadiq>
the write barrier tracks potential references from the major heap in to the minor heap
<olle>
Oh, someone on the forum compiled with ocamlc instead of ocamlopt, and then he/she could measure it
<sadiq>
also yes
<sadiq>
you can tell the compiler not to optimise stuff out
<sadiq>
use Sys.opaque_identity
<olle>
:d
<sadiq>
it basically puts it's parameter in a black box the optimiser can't see through
* olle
checking the docs
<sadiq>
also yes, there's a good chance the compiler isn't allocating the immutable record at all
<sadiq>
within the loop, at least
<sadiq>
oh it can just pull them all out
<Armael>
yea the record becomes static data
<Armael>
since it's the same at all loop iterations
<sadiq>
tbh I've been tripped up by that when writing benchmarks before
<Armael>
I wasn't sure where to put the Sys.opaque_identity, I tried (Sys.opaque_identity ignore) (Sys.opaque_identity q3)
<olle>
bwah
<Armael>
is this the proper amount of Sys.opaque_identity?
<olle>
Yes, I saw the same cmm code
<Armael>
(for replacing the last () in the body of the loop)
<olle>
But ok, if ocamlc works, maybe that's good enough :)
<sadiq>
ignore(Sys.opaque_identity(q3)) is probably what you want
<Armael>
ok
<olle>
hm, difference between the two loops is not big (using ocamlc)
<olle>
in php the diff was like 90% on my machine, but of course the code was a little bit different (still comparing immutable style to mutable)
<olle>
1s vs 1.1s with ocamlc
<olle>
hm
<olle>
so 10%
<olle>
Now for the same thing on JS...
<olle>
heh, 5x slower with spread operator in JS vs mutable fields.