[rkward-devel] JS in rkwarddev [was: splitting repos?]

Thomas Friedrichsmeier thomas.friedrichsmeier at ruhr-uni-bochum.de
Mon Oct 26 10:02:46 UTC 2015


Hi,

On Sun, 25 Oct 2015 17:23:51 +0100
meik michalke <meik.michalke at uni-duesseldorf.de> wrote:
> nice discussion, btw ;-)

same here!

[Again a long snip]

> > But why not write JS-code like e.g.
> > 
> > rk.paste.JS ("
> >   var x = getString ('", id (x), "');
> >   if (getBoolean ('", id (narm), "') {
> >     x += ', na.rm=TRUE';
> >   }
> > ")
> 
> you *can* do that, there are just various reasons why i wouldn't
> *like* to do it this way.
> 
> for once, i'd have to think in JS syntax again (like, don't forget to
> close your statement with ";"). this might be the main difference in
> our views on this -- if i understand you correctly, you would like to
> get back closer to the actual JS code, whereas i would like to get as
> close to R (or as far away from JS) as possible. both directions
> don't mix so easy :-o

That's a pretty good summary, indeed. I'll try to argue my point some
more, below.

> also, there wouldn't be any win here regarding the missing syntax 
> highlighting, because the JS code would need to be quoted (see below).

True. I concede that the "separte JS-file with templating" solution
does have the drawback of splitting the single master-file into two,
again, and of course implementing the required templating would not be
entirely trivial (contrary to implementing rk.JS.get() in a "single
file wiht quoting" solution). So that's why I'm giving up this goal
(for now). But reducing the language-mix is still be a useful goal, IMO
(also wrt your suggestion to view dev-script and generated JS
side-by-side: the closer the correspondence between the two, the easier
this can be done.

Actually, you _could_ at least take code like the above (the part
inside the outer quotes) and paste it into a JS highlighting window.
This would immediately reverse the HL into "JS appears real, R appears
quoted".

> then there's little things like "what was the getter function for
> this element again?" i tend to forget things like these all the time,
> and that's always slowing me down.

A valid point, but somewhat orthogonal to this discussion. Actually the
main point of the getters is to make sure you actually get the type of
data that you think you will get. The "universal" getValue() is still
around, but its problem is precisely that in some cases you will not
get the type of data you expected.

It is true that - for the most part - the "expected" data type
corresponds directly to the type of element/property you're dealing
with, and that in turn can be hard to memorize at times. But

a) this can logically be separated from the question of assigning a
variable or not, or the naming of that variable. Let's implement just
two additional functions:
  - rk.JS.get(x): automatic, universal getter, generates
    "getString('id_of_x')" (or whatever other getter is appropriate).
  - idq(x): returns the id of x, quoted, without surrounding space
    (i.e. probably special-cased by rk.paste.JS). To be used for
    "handwritten" JS code such as
      rk.paste.JS ('var x = getString (', idq (x), ');'
b) this still does not help you, if you're relying on the wrong type of
data, e.g. expecting a string, while you get a list of length 1, or
doing a boolean comparison, when you actually get a string.

> i don't want to even have to think
> about whether i have to declare this variable or not, for my taste
> that's too far down on the JS level.

Not all that different from variables in R, as far as I can see? And
in fact rkwarddev generates a lot of variable declarations that usually
I would not use at all: Esp. where the value in question is only used
once, or transformed, immediately.

Or are you talking about the "var" keyword? To tell you a dirty secret:
In most cases it's entirely optional. Using "var" on the first
occurrence ensures that you will be using a local variable. Which is
generally what you want. For the - rare - cases where you _don't_ want
this, i.e. you want to use a global variable common to preprocess(),
calculate(), and printout(), would that even be possible with
rkwarddev, ATM?

> i want to keep just to "if this
> box is checked, do that", so all i really have to care about is:
> 
>  ite(narm, "x += ', na.rm=TRUE'")
> 
> or quicker for checkboxes:
> 
>  tf(narm, opt="na.rm")
> 
> > > new way:
> > >   ite(jo(x != ""),
> > >     echo(", select=c(", x, ")")
> > >   )
> > > 
> > > that is, operators like !=, ==, > etc. are prevented from
> > > evaluation by jo() and pasted as-is to the JS code.
> > 
> > Neat hack! But not a path I'd like to go, personally. To be honest,
> > those ite()-statements just give me the shivers, in the first place.
> 
> oh, why's that? ite() is purposely almost identical to R's ifelse(),
> except it's allowed to use NULL for its "else" value, which also is
> the default. it's rather one of my favourites, because it's so easy
> to use...

Well:
1) ite(), jo(), and tf() are "R", but they're not something that R users
will immediately be familiar with. They are rkwarddev-isms. So it's not
like you're taking away the requirement to learn something new, you're
just making it something different.
2) R has ifelse(), but that's not the "usual" construct used for
flow-control. Quite the contrary, R's if()/else() looks remarkably
similar (identical in many-to-most cases) to if()/else() in JS. And one
important part about that is the curly braces {}. These may not seem
too important for the simple cases, but as soon as you start nesting
if()s, they are a life-saver.
Interestingly, JS (also C and many other languages), has a "ternary
operator" for conditional statements, too, although - for good reason -
it is not too wide spread. Some people hate it, others like it a lot,
but there seems to be consensus that it is a genuinely _bad idea_ to
nest such statements. Quite similarly, you won't encounter ifelse() in
R, too often. (Although one point, where R's ifelse(), really shines
beyond anything JS has to offer is using conditions on a vector:
  ifelse(1:10 %% 2, "odd", "even")
But that usage is not really related to ite().)

So that's why I would rather write JS if()-statements (which look
remarkably similar to R's if() statements), even if they are quoted,
rather than ifelse()-statements (which don't look similar to a typical
flow-control statement in either language).

> > (Ok, I would see the point, if you could actually move _all_ logic
> > from literal JS to R, but that does not seem to work out).
> 
> yeah, that would be optimal. and i agree, it's most likely never
> going to be achieved. 
> 
> > 
> > Why not write the above as:
> > 
> > rk.paste.JS ("
> >   var x = getString ('", id (x), "');
> >   if (x != '') echo (', select=c' + x + '));
> > ")
> 
> well, at least for now this gives us
> 
>   var x = getString ('
>   x
>   ');
>   if (x != '') echo (', select=c' + x + '));

I see. Well, see above. I suggest adding idq() to make it at least
_possible_ to write code like this (and remove one layer of quotes at
the same time).

> instead of what rk.JS.scan() + ite() generate: 
>   var x = getString("x");
>   if(x != "") {
>     echo(", select=c(" + x + ")");
>   }
> 
> what's more, the ite() example has proper syntax highlighting:
>  http://reaktanz.de/stuff/R/JS_examples.jpeg
> which would immediately warn you about that missing single quote in
> the echo() call that you easily miss in the fully quoted JS code.

To me this shows:
  - For simple cases ite() is not quite as evil as for complex cases ;-)
  - rkwarddev's echo() may sometimes be useful to reduce quoting
    madness. But fortunately, that does not make it necessary to use
    ite() at the same time:

rk.paste.JS ("
  var x = getString ('", idq (x), "');
  if (x != '') {",
    echo (', select=c(' + x + '))';
  ,"}
")

  - For cases _not_ covered by echo() and friends, writing it manually
    is still the better option wrt quoting:

rk.paste.JS ([...]"
  var x = getString ('", idq (x), "');
  if (x != '') {
    opts += ', select=c(' + x + ')';
  }
")

- compared to -

rk.paste.JS ([...]
  ite(jo (x != ""),
    "opts += ', select=c(' + ", x, " + ')'"
  )
)

(Did I even get that right?)

> just a vague idea: would it be possible to make the syntax
> highlighting scheme of RKWards R console *output* configurable? it's
> plain green by default, if you could (temporarily) set that to use
> one of kate's highlighting schemes (e.g., XML or JS), this would at
> least make debugging rk.JS.* statements on a console level easier --
> you wouldn't have to wait for files to be written. no idea if this is
> simply a character stream that could easily be pumped through a
> highlighting filter before it's shown on screen.

Not easily, I think. It is possible to nest highlighting defintions
(although I don't recall the details, ATM), e.g. as done for HTML
inside PHP, etc. But that's still done statically, not something you
can configure on the fly, per output section.

It would be easy enough to provide JS/XML highlighting via
rk.print.code(), though (in the output window), if that helps any.

Regards
Thomas
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://mail.kde.org/pipermail/rkward-devel/attachments/20151026/e2fcd647/attachment-0001.sig>


More information about the rkward-devel mailing list