Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
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
hiiamboris
@hiiamboris

There's also a concern of in what sequence the results are inserted: in the code

>> x: [] collect/into [loop 5 [parse [3] [(keep 1 append x 2) collect into x keep skip]]] x
== [3 3 3 3 3 1 2 1 2 1 2 1 2 1 2]

the result will depend strongly on the implementation of each insertion operation.
I think append at the core of keep is easiest to reason about and implement, and keeps one safe from forgetting to provide series tail to collect/into. Isn't that the complexity reduction we're all striving for? ;)

BeardPower
@BeardPower
@hiiamboris Why you would want append? How about appending things!?
hiiamboris
@hiiamboris
:D don't append on me bro
Vladimir Vasilyev
@9214
@hiiamboris can you explain how this ever related to the crux of my request?
Vladimir Vasilyev
@9214
FYI, first snippet has minuscule advantage on time scale (also works much faster with x: removed which you may have intentionally placed there), and consumes less memory, which also adds to confusion of what your point is.
hiiamboris
@hiiamboris
@9214 my point was never about what index to return, but rather where to insert stuff. Maybe that confused you initially, but I believe you're able to see thru it without any additional remarks.
Vladimir Vasilyev
@9214
While keeping? I'd prefer insert, because it gives more tight control over inserting position, but I see that append is the most common need, and also doesn't have the overhead associated with moving portions of memory.
hiiamboris
@hiiamboris
Yes, that's it. Plus there arises a consistency problem with the keep from parse, which is trivially solved by append.
Nenad Rakocevic
@dockimbel

@loziniak

It's sad because you sometimes have to work with callbacks, when you want to use C library that uses them.

R/S has no issue passing callbacks to imported functions from external C libraries. Such feature is used in many places in the Red's runtime library souce code.

Between R/S functions, passing a pointer! instead of a function!, then casting it to a function! works fine.

@9214 Please open a ticket for the missing object events firing (if that's the issue).
Vladimir Vasilyev
@9214
@dockimbel the issue is that object does not "re-own" a series to which one of its fields was set.
Nenad Rakocevic
@dockimbel
Can you point me to an example?
Vladimir Vasilyev
@9214
Guh, Gitter search, not again...
Gimme a sec :wink:
Nenad Rakocevic
@dockimbel
Ah wait, found it.
Vladimir Vasilyev
@9214
r: make object! [
    a: [1 2 3]
    b: [4 5 6]

    on-deep-change*: func [owner word target action new index part][
        print ['on-deep-change* tab word]
    ]

    on-change*: func [word old new][
        print ['on-change* tab word]
    ]
]

reverse/part r/a 2
r/a: [3 2 1]       ; <-- set field to a new series which object does not 're-owns'
reverse/part r/a 2 ; I expect this to fire on-deep-change*, but since new series is not owned by an object...
Nenad Rakocevic
@dockimbel
Yes, an object will only own automatically the series used when creating it. After that, it's up to the user to manually attach/detach series from the object. If you don't want to do the work yourself, you can use reactor! or deep-reactor! instead, which provide general event handlers for that: https://github.com/red/red/blob/master/environment/reactivity.red#L30 (you can also extract the relevant lines from there and build your own event handler, and bypass the reactive stuff to improve performance).
Vladimir Vasilyev
@9214
@dockimbel so it's either insert clear r/a [3 2 1] or something else?
Like, I don't know, own new function inside -change* or something like that.
I see your edited message, thanks! @nedzadarek :point_up:
Nenad Rakocevic
@dockimbel
@9214 I haven't followed the discussion, so don't know what you're asking for.
Vladimir Vasilyev
@9214
@dockimbel I've asked how to mark series as owned by an object manually, instead of relying on reactor! handlers, but you already pointed out the direction.
Nenad Rakocevic
@dockimbel
modify action allows you to set or unset series flags.
Vladimir Vasilyev
@9214
Aha! I see now.
hiiamboris
@hiiamboris

omg.. I'm at a loss guys

collect1: :collect
collect2: func spec-of :collect body-of :collect
profile/count/show [
    [collect1 [repeat i 10 [keep i]]]
    [collect2 [repeat i 10 [keep i]]]
] 10000
Count: 10000
Time         | Time (Per)   | Memory      | Code
0:00:00.138  | 0:00:00      | 8978432     | [collect1 [repeat i n [keep i]]]
0:00:00.214  | 0:00:00      | 11243520    | [collect2 [repeat i n [keep i]]]

is magick at work here?

Toomas Vooglaid
@toomasv
@hiiamboris Interesting!
>> profile/count/show [[collect [repeat i 10 [keep i]]][collect1 [repeat i 10 [keep i]]][collect2 [repeat i 10 [keep i]]]] 10000
Count: 10000
Time         | Time (Per)   |      Memory | Code
0:00:00.123  | 0:00:00      |     8978432 | [collect [repeat i 10 [keep i]]]
0:00:00.131  | 0:00:00      |     8978432 | [collect1 [repeat i 10 [keep i]]]
0:00:00.184  | 0:00:00      |    11243520 | [collect2 [repeat i 10 [keep i]]]
>> profile/count/show [[collect [repeat i 10 [keep i]]][collect1 [repeat i 10 [keep i]]][collect2 [repeat i 10 [keep i]]]] 10000
Count: 10000
Time         | Time (Per)   |      Memory | Code
0:00:00.123  | 0:00:00      |     8978432 | [collect1 [repeat i 10 [keep i]]]
0:00:00.125  | 0:00:00      |     6877184 | [collect [repeat i 10 [keep i]]]
0:00:00.183  | 0:00:00      |    11243520 | [collect2 [repeat i 10 [keep i]]]
>> profile/count/show [[collect [repeat i 10 [keep i]]][collect1 [repeat i 10 [keep i]]][collect2 [repeat i 10 [keep i]]]] 10000
Count: 10000
Time         | Time (Per)   |      Memory | Code
0:00:00.122  | 0:00:00      |     6877184 | [collect1 [repeat i 10 [keep i]]]
0:00:00.123  | 0:00:00      |     8978432 | [collect [repeat i 10 [keep i]]]
0:00:00.195  | 0:00:00      |    11243520 | [collect2 [repeat i 10 [keep i]]]
nedzadarek
@nedzadarek

@9214

I see your edited message, thanks! @nedzadarek :point_up:

Hmm... what message?

@toomasv @hiiamboris isn't collectand collect1 compiled hence faster?

hiiamboris
@hiiamboris
it's not a native!, how is it compiled?
moreover in all tests of compiled vs interpreted code I've tried - interpreted was faster by 20% or so ;)
Toomas Vooglaid
@toomasv
@nedzadarek I think @9214 referred to @dockimbel's message just before it
nedzadarek
@nedzadarek
@hiiamboris I don't know the proper terms but here is an example (view uses layout):
layout: func spec-of :layout head insert (body-of :layout) [print "hello from new layout"]
view [base red]
view layout [base red]
; hello from new layout
nedzadarek
@nedzadarek
@toomasv ah, I see, thank you
Nenad Rakocevic
@dockimbel

@hiiamboris

it's not a native!, how is it compiled?

native! are written in R/S, function! are written in Red, and the ones provided by the runtime (the so-called "mezzanines") are compiled, hence the difference.

@hiiamboris

moreover in all tests of compiled vs interpreted code I've tried - interpreted was faster by 20% or so ;)

That would be odd, I suspect something is flawed with your measurement method. Remember that blocks of code run by do cannot be compiled (by design, as it's the way to invoke the interpreter).

Vladimir Vasilyev
@9214
@nedzadarek you were interested in how to roll out your own event handlers, @dockimbel pointed out the direction in his message.
hiiamboris
@hiiamboris

@dockimbel cool! I didn't know we can reflect the source of compiled funcs.
And you're right, I was using loop N [do code] since the compiler won't let me compile loop N code, so that explains it all, thanks!
Just checked:

x: 0
f: does [x: x + 1]
t: [now/precise/time/utc]
t1: do t
loop 1000000 [f]
t2: do t
print t2 - t1

is really about 2x faster when compiled

hiiamboris
@hiiamboris
Imbued collecta bit with more magic :) Faster, less allocation-prone. Makes sense only for compiled code though or for small collections (n < 10) https://gist.github.com/hiiamboris/a624c3d767dfe4e4ed20f23bc96433ff
Nenad Rakocevic
@dockimbel
@hiiamboris Nice work! :+1:
hiiamboris
@hiiamboris
@dockimbel thanks :) the only drawback is that I can't meaningfully reflect it, not with the context parts...
nedzadarek
@nedzadarek
@hiiamboris I'm confused about your usage of also. Why not just body': body coll': coll' shoot :keep coll?
How do you modify an owner the series/object? noneing old's owner works fine but when I try to modify new series I get access violation at the last line (reverse/part r/a 2):
r: make object! [
    a: [1 2 3]
    b: [4 5 6]

    on-deep-change*: func [owner word target action new index part][
        print ['on-deep-change* tab word]
    ]

    on-change*: func [word old new][
        print ['on-change* tab word]

      unless all [block? :old block? :new same? head :old head :new][
              if any [series? :old object? :old][modify old 'owned none]
              if any [series? :new object? :new][modify new 'owned reduce [self word]]
      ]
    ]
]

reverse/part r/a 2
r/a: [3 2 1]       ; <-- set field to a new series which object does not 're-owns'
reverse/part r/a 2
Vladimir Vasilyev
@9214
@nedzadarek red/red#3393
nedzadarek
@nedzadarek
@9214 great, thank you
hiiamboris
@hiiamboris

@hiiamboris I'm confused about your usage of also. Why not just body': body coll': coll' shoot :keep coll?

also keeps the old value and restores it after leaving the next (...) scope, otherwise you'll break the recursive test

GiuseppeChillemi
@GiuseppeChillemi
could a function know its name ?
mynicename: func [arg1] [some code here]
Could "some code here" know its name is "mynicename"
nedzadarek
@nedzadarek
@GiuseppeChillemi as fair I remember functions are anonymous but you can create "function creator" that have function name, something like this:
named-func: func [_func-name spec body] [func spec bind body context [func-name: _func-name] ]
foo: named-func 'foo [a b] [probe a + b probe func-name]
foo 2 3
; 5
; foo
you can use set so you don't have to repeat yourself (foo: named-func 'foo):
named-func2: func [_func-name spec body] [set _func-name func spec bind body context [func-name: _func-name] ]
named-func2 'qux [a b] [probe a + b probe func-name]

qux 2 3
; 5
; qux
hiiamboris
@hiiamboris
@GiuseppeChillemi
>> myniceop: make op! func [name [set-word!] fn [function!]] [also set name :fn replace/all/deep body-of :fn 'func-name to-lit-word name]
>> mynicename: myniceop func [x y] [print [x y "from" func-name]]
>> mynicename 1 2
1 2 from mynicename
Vladimir Vasilyev
@9214
@GiuseppeChillemi functions are anonymous and can be referred by multiple words, so "name" is not the best term.
>> foo: has [dummy][print pick find body-of system/words context? 'dummy -1]
== func [/local dummy][print pick find body-of system/words context? 'dummy -1]
>> foo
foo
You can keep a word from context other than system/words to be more flexible.
githubnyn
@githubnyn
is there a way to initialize a word that is undefined ?
something like:
counter: function [][
    if not value? count [count: 0]
    count: count + 1
]
counter