## Where communities thrive

• Join over 1.5M+ people
• Join over 100K+ communities
• Free without limits
• Create your own community
##### Activity
• Oct 20 2019 22:59
@dockimbel banned @SmackMacDougal
• Dec 03 2017 05:53
@PeterWAWood banned @matrixbot
• Sep 28 2016 12:19
@PeterWAWood banned @TimeSeriesLord
• Aug 13 2016 03:23
@PeterWAWood banned @Vexercizer
@9214 then I need to study it with fresh mind (sorry, it's night here)
@9214
@nedzadarek sure, it's night here too ;)
@hiiamboris except that your x is now leaking into global context
hiiamboris
@hiiamboris
hmm okay, add it to /locals then
@hiiamboris other function can use x and every one would use different x(assuming /local x)
@9214
And it will last only for the next function, in the worst-case scenario you need to prepend x: 1 to each and every nested body.
And change /local part.
hiiamboris
@hiiamboris
=( I don't understand... can you make a quick example?
@9214
I don't understand it either, and it's 4:30 AM here.
@9214 it's morning not night ;)
hiiamboris
@hiiamboris
oh I think I see what you mean, that next specialize invocation will have to read that x: 1 and append y: 2 to it
but it can read that, right? if it prepends it in the form set [vars] [values], this form stands
@9214
@hiiamboris kinda like that, yes, you then need to store/update those arg/value blocks somewhere, populate bodies on each invocation with them, and change /local ... in specs.
@nedzadarek night is in my mind. :zzz:
hiiamboris
@hiiamboris
can store them at the start of the body, why not?
func [x y z][loop 5 [print x: x + 1]]
x=1 => func [y z /local x][set [x][1] loop 5 [print [x: x + 1]]
y=2 => func [z /local x y][set [x y][1 2] loop 5 [print [x: x + 1]]
z=3 => func [/local x y z][set [x y z][1 2 3] loop 5 [print [x: x + 1]]
@9214
@hiiamboris it's the other way around - you apply function to one argument and it returns you func [y][...] with other nested functions inside it.
But x value should be preserved somehow, so that those nested functions are able to access it. Same with other arguments.
And this is what closure does - it references a variable in the scope where it was defined.
Localization is an interesting approach, I didn't think about that much.
hiiamboris
@hiiamboris
what if specialize returned a wrapper to itself until there's no more arguments to apply?
@9214
I'd rather wrap myself in a blanket now.
hiiamboris
@hiiamboris
;)
@9214

@9214

you apply function to one argument and it returns you

Well... I need some sleep

hiiamboris
@hiiamboris
to clarify the point above:
spec(x0,f(x,y,z)) when called returns spec(y0,f(y,z,x=x0)), and the new one => f(z,x=x0,y=y0)
so you only have to call spec() once on a normal function to construct a currying variant, and then each call just adds an argument until there's only one argument remains and the function itself is returned
it's all great in theory though, but in practice a returned function will be just data (it won't accept arguments yet), so you'll need an operator (or do reduce [..]) to call it
hiiamboris
@hiiamboris
@9214 as a master bindologist, might you have any insight on the following performance data?
x: 1
....
0:00:00.442000001 [get in context? 'x 'x]
0:00:00.238000001 [get bind 'x context? 'x]
Gregg Irwin
@greggirwin
@hiiamboris, bind and in do their work differently, as you can see in the R/S code. We'd have to profile the internals to see what's slower, aside from obvious overhead of extra func calls between find-word/bind-word. Doc might say, but he's busy.
@dockimbel
@hiiamboris in requires a stack slot copy while bind just modifies the first argument slot on stack, and re-use it as returned value. The incurred overhead exists because such copy boils down to an expensive memcpy(), which could be replaced in a future (once we start working on optimizations) by a simple read/write using an SSE 128-bit wide register. Once such optimization is done, the difference should become insignificant.
hiiamboris
@hiiamboris
hmm.. interesting, thank you @dockimbel !
@9214
Guh, I'm late :(
@hiiamboris my answer would the basic version of @dockimbel's - bind modifies context pointer in slot and returns it, while in allocates an extra copy, so as to avoid modification of the original word (I guess?).
lepinekong
@toomasv I can't find composite in help ?
Toomas Vooglaid
@toomasv
@lepinekong_twitter :point_up: April 6, 2018 1:14 AM
lepinekong
I feel frustrated: why this basic switch doesn't work :smile:
type: word!;

probe type? type ; datatype!
probe type? word! ; datatype!
probe (type = word!); true

switch type [

unset! [
print "unset!"
]
word! string! file! url! block! [
print "word! string! file! url! block!"
]
]
@9214
@lepinekong_twitter switch type?/word
lepinekong
@toomasv ah ok thanks I didn't remember
@9214 that's my point why would I need type?/word since type? type and type? word! are same so that (type = word!)
@9214
>> switch 'word! [word! [print "word!"]]
word!
@lepinekong_twitter you're switching by datatype, but your block contains words.
lepinekong
value [any-type!] "The value to match".
@9214
>> block: [word! [print "word!"]]
== [word! [print "word!"]]
>> type? word!
== datatype!
>> type? block/1
== word!
>> type? type? block/1
== datatype!
>> type? type?/word block/1
== word!
lepinekong
@9214 so inside block it becomes word ? but why value is of type any-type! instead of word!
@9214
What any-type! has to do with that?
lepinekong
according to help
every value is any-type!