Skip to main content

News

Topic: Link.js v0.4.2 (Read 95878 times) previous topic - next topic

0 Members and 5 Guests are viewing this topic.
  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: Link.js v0.2.12
Reply #180
It's still an extra level of indirection, which may confuse people--if you're passing in a function for this, I can't imagine it's any slower to just use a full filter() referencing the same property.  Like this:

Code: (javascript) [Select]
function filterFunc(item) { return item.prop == "find me"; }
var items = Link(array).filter(filterFunc).toArray();


I imagine that gets you the same benefits (the function is pre-declared and always references the same property so the compiler can optimize it) as Radnen's proposed change to filterBy(), and is clearer to someone skimming over the code than this:
Code: (javascript) [Select]
function resolve(item) { return item.prop; }
var items = Link(array).filterBy("find me", resolve).toArray();
  • Last Edit: June 07, 2014, 11:33:23 pm by Lord English
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Link.js v0.2.15
Reply #181

It's still an extra level of indirection, which may confuse people--if you're passing in a function for this, I can't imagine it's any slower to just use a full filter() referencing the same property.  Like this:

Code: (javascript) [Select]
function filterFunc(item) { return item.prop == "find me"; }
var items = Link(array).filter(filterFunc).toArray();



Yes, ultimately that is the fastest solution. So in that regard, if you really need the speed for a dire and critical loop, doing just that will indeed speed you up. So I think all bases are covered. I won't go with the resolve approach any longer, but I think it was still a neat exercise in how JS can still be made fundamentally faster by doing little tricks like that.

(btw v0.2.15 is out)
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: Link.js v0.2.15
Reply #182
So just to be clear, random() still won't choose the same item more than once, correct?  So if I request 2 items and there's only one that matches the query, I'd only get an array of length 1 as the result?  Hm, looks like I will have to keep doing it the way I'm currently doing it for this particular case, but good to know I won't get an array with undefined entries anymore anyway! :-)
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Link.js v0.2.15
Reply #183

So just to be clear, random() still won't choose the same item more than once, correct?  So if I request 2 items and there's only one that matches the query, I'd only get an array of length 1 as the result?  Hm, looks like I will have to keep doing it the way I'm currently doing it for this particular case, but good to know I won't get an array with undefined entries anymore anyway! :-)


Yeah, it was made to take unique random samples. Uhh, hmmm... I could add a unique argument to it if you want so you can toggle between not unique and unique, it wouldn't be too much to add.
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: Link.js v0.2.15
Reply #184
Yeah, my use case is this: The boss's AI picks two random move chains from a list of them, like this:

Code: (javascript) [Select]
var combos = Link(Link(this.combos)
    .where(function(combo) { return this.phase >= combo.phase; }.bind(this))
    .random(2))
    .sort(function(a, b) { return b.rating - a.rating; });


And uses them against the two PC battlers, the less powerful one being used against one battler as a distraction while the "real" tactic is being set up under the player's nose.  The thing is, there's no reason the two combos picked have to be unique--the boss could very well choose to use the same tactic against both.  Right now though, to allow this, I have to invoke the RNG myself, and then manually test which of the two tactics chosen has the higher rating--something the sort would do for me, besides being more scalable if at some point I decide to have more than 2 PCs.

How about this: Make random() and sample() distinct.  The former would pick random items without a uniqueness check, while sample() would give unique samples.  Since they're separate use cases, I think this is a better solution than taking an additional parameter.
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Link.js v0.2.15
Reply #185
Sure, I like that a lot. Random = multiple returns, while sample = unique returns.

I have just now added concat. But this is a lazy concat. Picture doing this:
Code: (javascript) [Select]

Link([1, 2, 3]).concat([1, ..., 1000000]).take(5).toArray();


In a traditional style, it'll concat the first 3 items to the other million items then strip out and return the first 5. In Link it will say, "oh run the query and add the first 3 items, then two more and quit". It should be really fast. :)

Edit: ok, it is done. I'm still calling this v0.2.15 until I have ran out of ideas, then I'll push it officially as a release.
  • Last Edit: June 08, 2014, 01:03:46 am by Radnen
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: Link.js v0.2.15
Reply #186
That's awesome.  I can't imagine any use cases for it yet, but I'm slowly finding uses for many Link functions I originally thought useless as I've been programming my boss AIs, so who knows. :-)

Besides core game engine stuff, Link seems to be an awesome tool for writing RPG battler AIs--it allows me to simplify so many complex checks and decisions made by the AI into a line or two that would otherwise end up as a massive tower of if conditions or similar.

edit: Just looked at the commit for lazy-concat, looks like you also allow Link contexts to be concatenated as well.  That's a nice touch. :D  Although you may want to note that such feature exists in the documentation...
  • Last Edit: June 08, 2014, 01:15:55 am by Lord English
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Link.js v0.2.15
Reply #187
I'm planning on adding more things over to Link contexts, so as to make it seamless.

The documentation is really going to be something that will take time. I haven't yet made any formal documentation and am totally planning to do this at some point of time. The sooner the better.

I want to get my own webspace sometime within the week, then make myself a personal website and put the link documentation there. That's the overarching plan.

I'm going to add join now.
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: Link.js v0.2.15
Reply #188
Are Link contexts immutable, or no?  For example, if I do:

var q = Link(array).filterBy('eatenness', 812)

Can I later re-use q with different operations, or will that mutate the context and cause issues?  This is something I've been wondering about for a while.

Oh, and I know there's no formal docs yet, I just meant in the readme, there's no indication that concat will accept another Link context in place of an array.
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Link.js v0.2.15
Reply #189
Yes, you can resuse q with different operations. The contexts are immutable as of v0.2.6, so there won't be issues if you decide to store a partial chain, then tack stuff on to it. In fact it's really efficient that way!

I'll try updating more docs as I add more Link integration in its own methods.

I was able to add split, finally. It's not flawless in fact it relies on me appending a "\0" to the end of a string. It sucks, I know, but there's no way of telling whether or not you reached the end of a string in JS, and there's no way of telling wther you are on the last element of a Lazy-executed chain. It works for my small battery of tests on it, so I think it's okay to do so. Though I wonder what the impact is to innocuously add a new element to the end of a string. Otherwise I can't see any way to do this without first resolving the end of a chain by running it, then splitting, then continuing in an entirely new link context. (Which is not necessarily lazy execution by any means). So this shall suffice.

I also added Join. Now there was an SQL-like join already in it, but this is an array join where it returns a string delimited by the character you choose to use.

Join is not lazy, because it returns a compiled instance: the string of the contents joined together. Split on the other hand is lazy and useful for splitting a few elements out of, say, a million.

Say you have a million words separated by spaces but want the first 5:
Code: (javascript) [Select]

var words = Link(long_story).split(" ").take(5).toArray();


I see uses for this in dialog scripts all over the place. And it's fast too since the entire conversation doesn't need to be split, just the first few words or a section of words you decide to choose.

Split cannot detect the future, though, so:
Code: (javascript) [Select]

var words = Link(story).split(" ").skip(5).take(5).toArray();

Means 10 words still need to be split, but no more.

...I could implement a new splitSkip() method that will skip the first n occurrences of a delimiter, but that's the best it gets for Link.
  • Last Edit: June 08, 2014, 03:37:50 am by Radnen
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: Link.js v0.2.15
Reply #190
JS strings have a length property, just like arrays.

Code: (javascript) [Select]
Abort("Scott Starcross".length);

...prints 15.  Can't you use that to determine when you reached the end instead of appending nulls?
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Link.js v0.2.15
Reply #191
Because you can filter out stuff.

Code: (javascript) [Select]

return Link("Scott Starcross").reject(["s", "t", "a", "r"]).split(" ").toArray(); // ["Sco", "Sco"];


The length will say 15, but the filter now makes it 6, and this is just a simple example. When it reaches the last 'o' it must end after 6 iterations rather than the last s after 15 iterations.
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: Link.js v0.2.15
Reply #192
Well in any case, appending nulls shouldn't have any side effects, since JS strings are immutable.  On the flipside, however, that may represent a performance hit if the input string is long enough, since even something as simple as appending a single character means the whole thing has to be copied.
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Link.js v0.2.15
Reply #193

Well in any case, appending nulls shouldn't have any side effects, since JS strings are immutable.  On the flipside, however, that may represent a performance hit if the input string is long enough, since even something as simple as appending a single character means the whole thing has to be copied.


Yeah, I was thinking the same thing about how JS appends characters and the performance of doing so. It varies per engine, but from reading stack overflow I think in FF a string appended in such a way is like a linked list in which case the first very long immutable string is kept unaltered in memory and appending something to the end still happens lightning fast since a pointer is generated saying: "wait there's more!". In FF the hit is only taken when reproducing all of the string since all nodes on the linked list must be visited, but in Link.js each character is met one at a time, so unless it has to read the last letter, it shouldn't be much of an issue. I don't know how Chrome works, but I think it's more on the cstring side where memory is reallocated and added when you append characters, but I might be wrong here. V8 keeps changing too fast!
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: Link.js v0.2.15
Reply #194
The only other issue I can think of is if the input string already contains '\0' characters to start with, but since the use case here is primarily text, that shouldn't crop up very often, if at all.  We're not parsing binary data after all. :)
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub