Re: local 'in' syntax

  • From: Eric Man <meric.au@xxxxxxxxx>
  • To: luajit@xxxxxxxxxxxxx
  • Date: Wed, 4 May 2016 11:12:39 +1000

Following this thread, gave me the idea on how to implement this feature in
plain lua as a hack, so one can import like:

        local exp, log, sin, cos, tan within (math, 5)

without having to use incompatible syntax.

https://gist.github.com/meric/1883adb92044b75237bb0b42a63d5ed4

I have not figured out how to phase the "5" out. It's used to figure out
how many local variables to be assigned.

On Wed, May 4, 2016 at 7:34 AM, Demi Obenour <demetriobenour@xxxxxxxxx>
wrote:

I like this idea a lot.  It solves a really annoying problem.

On Mon, May 2, 2016 at 11:16 AM, Laurent Deniau <Laurent.Deniau@xxxxxxx>
wrote:


On 02 May 2016, at 16:28, Elias Hogstvedt <eliashogstvedt@xxxxxxxxx>
wrote:

So you don’t use FFI nor JIT options, nor table.new or other useful
features part of LuaJIT? You don’t use _ENV in Lua PUC? Does it means that
you will stay with Lua 5.1 forever? (just to be provocative ;-)

I use these things but if I were to make a public lua module I would
probably check for the availability of ffi and other things. When you have
difference in syntax this becomes difficult. This change wouldn't break
anything existing and I probably wouldn't mind if lua had this syntax
really. I just wanted to point out the slippery slope (from your previous
lambda patch) here.

Which is a good thing IMHO… Globals are error prone, except for very
well established names.

People choose their own variable names and so you often have to go to the
top of the file to see what the function originally is. It's very clear
what table.insert is but it's not immediately clear what tinsert, insert,
add, push, ti, etc is. It also breaks syntax highlighting if you use that.


Right, that is why I will not implement the ‘as’ of Python...

And I never said that it should be part of the trunk, I provide the
patches for who might be interested. Most users don’t even compile LuaJIT
or Lua, they just use the default downloaded version.

And it probably sounds like I think you want these to be part of the
trunk. I just like discussing. :)


I propose, people dispose…

For example, I will not propose my next patch as it is more related to
math specific applications and it changes the semantic of Lua for one very
special case of coercion that I dislike… Since I disagree with this
semantic, I will change it in my application…

Best,
Laurent.

On Mon, May 2, 2016 at 2:51 PM, Laurent Deniau <Laurent.Deniau@xxxxxxx>
wrote:


On 02 May 2016, at 13:37, Elias Hogstvedt <eliashogstvedt@xxxxxxxxx>
wrote:

Syntactically backwards compatible.


So you don’t use FFI nor JIT options, nor table.new or other useful
features part of LuaJIT? You don’t use _ENV in Lua PUC? Does it means that
you will stay with Lua 5.1 forever? (just to be provocative ;-)

If you're writing a lua module with your syntax it would only work in
that specific version of lua (as I'm sure you know). I'm interested in the
idea of moving away from lua syntax but then it should be a clear
distinction and it shouldn't be called lua anymore. One of the reasons I
like lua is because it has a very simple syntax that's easy to understand.

This localize thing isn't very on topic here but you've proposed a
change in syntax to make this problem easier to deal with.


you can see it as a missing feature of Lua, that many other programming
languages have. For example in Python it is the ‘from' qualifier of an
‘import'. The fact that modules are tables in Lua makes this feature even
more generic and useful, e.g. to extract component from tables to enhance
readability:

local x, y, z in vec
— here are lengthy expressions with x, y, z

instead of

local x, y, z = vec.x, vec,y, vec.z — easy to swap .x and .y by mistake
in LHS vs. RHS.
— here are lengthy expressions with x, y, z

My main issue with this localize everything mentality is that it makes
globals useless.


Which is a good thing IMHO… Globals are error prone, except for very
well established names.

When should we use globals? Would you localize math functions if luajit
optimized accessing globals in a way that made it just as optimal?


Are you sure that math functions are globals? I would say that math is
global, but not the functions. And yes I prefer by far

local sin, cos, tan in math

— use sin, cos, … as I would in math code.

I prefer to close (in the CS meaning) as much as possible, so this
feature enforces also better design in your application.

It seems like a hack or a workaround to me.

I don't know much about jit and compilers but I would've thought if you
used math.sin in a function it would skip looking up _G and math for the
sin function and just use it directly unless _G or the math table changes
which would recompile the function. Is that a naive way of going about it?


In fact, optimisation is one concern, readability is more important for
me. For example I have actually statement like below to avoid my code
looking like Java with lengthy.dot.path.down.to.functions:

local gmath   = require 'gmath'
local is_number, is_complex, is_scalar,
      is_matrix, is_cmatrix, is_amatrix,
      is_vector, , is_cvector, , is_avector,
      real, imag, conj, ident, min,
      abs, arg, exp, log, sqrt, proj,
      sin, cos, tan, sinh, cosh, tanh,
      asin, acos, atan, asinh, acosh, atanh,
      unm, mod, pow, tostring =
      gmath.is_number, gmath.is_complex, gmath.is_scalar,
      gmath.is_matrix, gmath.is_cmatrix, gmath.isa_matrix,
      gmath.is_vector, gmath.is_cvector, gmath.is_avector,
      gmath.real, gmath.imag, gmath.conj, gmath.ident, gmath.min,
      gmath.abs, gmath.arg, gmath.exp, gmath.log, gmath.sqrt, gmath.proj,
      gmath.sin, gmath.cos, gmath.tan, gmath.sinh, gmath.cosh,
gmath.tanh,
      gmath.asin, gmath.acos, gmath.atan, gmath.asinh, gmath.acosh,
gmath.atanh,
      gmath.unm, gmath.mod, gmath.pow, gmath.tostring

will be soon converted to:

local is_number, is_complex, is_scalar,
      is_matrix, is_cmatrix, is_amatrix,  is_vector, , is_cvector, ,
is_avector,
      real, imag, conj, ident, min, abs, arg, exp, log, sqrt, proj,
      sin, cos, tan, sinh, cosh, tanh, asin, acos, atan, asinh, acosh,
atanh,
      unm, mod, pow, tostring in require ‘gmath'

The big difference, is if I need to add one more function from the gmath
module, I don’t need to carefully check the shift in LHS vs. RHS, nor wrap
the lines on the LHS according the length of the (longer) lines on the
RHS...

As I said, I like when a language is minimal like Lua, but in some cases
(e.g. DSL) expressive power and readability matter. What is important, is
that syntactic extensions do not affect the semantic of the language which
is already very complete. Modifying the semantic must be done with care!
And I never said that it should be part of the trunk, I provide the patches
for who might be interested. Most users don’t even compile LuaJIT or Lua,
they just use the default downloaded version.

Best,
Laurent.

On Mon, May 2, 2016 at 12:38 PM, Laurent Deniau <Laurent.Deniau@xxxxxxx>
wrote:


On 01 May 2016, at 12:35, Elias Hogstvedt <eliashogstvedt@xxxxxxxxx>
wrote:

As you've probably noticed lua users aren't too keen on modifying the
Lua syntax. I personally like seeing efforts like this because I think it's
interesting but I would never use it myself. Being compatible with Lua
syntactically is something I think is important.


LuaJIT is already not compatible with Lua 5.2 and 5.3. so it’s a fake
argument unless you stick to 5.1 + few extensions.

On the other hand this whole "local sin = math.sin" thing is annoying
to both read and write.


Not only, now that the patch is supporting expr on the RHS, it also
allows to simplify your module design, i.e. they can return array of values
without any loss of clarity on the user side. I have many cases like this
where I was creating “fake” modules to return single value (i.e.
constructors) belonging internally to the same module:

local vector   = require “vector"   — returns xmatrix.vector, load
matrix first
local cvector = require “cvector" — returns xmatrix.cvector, load
matrix first
local matrix   = require “matrix”   — returns xmatrix.matrix
local cmatrix = require “cmatrix” — returns xmatrix.cmatrix, load
matrix first

with all the intricacy to load in the right order the requirements
(e.g. matrix module itself). With local ‘in’ syntax, I just need a single
module

local matrix in require “matrix” — ok and simple
local vector, cvector, matrix, cmatrix in require “matrix” — ok and
simple, same syntax...

So for me, it is not convenient and less error prone, it also affects
(simplify) the way you organise your module. I would not spend my time to
add only syntactic sugar, unless it has a deep impact on software design.
This is the case for the two patches I recently proposed. And I don’t have
any other need in mind about syntax. Maybe in the coming year I will give a
try to compile FNEW when there is no upvalue (to allow better optimisation
of local use of lambda) or extend the sink optimisation to a bit bigger
size (e.g. 512 bytes) and small VLA , but it’s a rather harder thing and I
have no idea how to do it.

  I don't wanna do it in my own code unless it shows actual performance
benefits from a user point of view. Especially when I think this can be
automated through preprocessing. (replace all instances of math.sin with
math_sin and add local math_sin = math.sin on top of the script)

I'll probably experiment with this now. I haven't tried this local
thing that much but the times I did I don't remember seeing any performance
benefits. However looking up something in _G that is nil seems especially
slow.


Best,
Laurent.

--

Laurent Deniau                           http://cern.ch/mad

Accelerators Beam Physics        mad@xxxxxxx
CERN, CH-1211 Geneva 23       Tel: +41 (0) 22 767 4647


On Sat, Apr 30, 2016 at 8:33 PM, Laurent Deniau <Laurent.Deniau@xxxxxxx
wrote:

On 30 Apr 2016, at 20:30, Laurent Deniau <Laurent.Deniau@xxxxxxx>
wrote:

Dear All,

I have extended the parser of LuaJIT to support the local ‘in’ table
notation in Lua. This extension is particularly useful for LuaJIT
considering the frequent needs to have local copy for performance reason.
The patch is very minimal and simple and extends the parser with only 13
lines.

The syntax extension allows to write:

local exp, log, sin, cos, tan in math

in place of:

local exp, log, sin, cos, tan in math.exp, math.log, math.sin,
math.cos, math.tan


I wanted to mean =

local exp, log, sin, cos, tan = math.exp, math.log, math.sin,
math.cos, math.tan

and avoid mismatch between variables and fields.

The patch is activated by
XCFLAGS+= -DLUAJIT_LOCAL_INTABLE
in Makefile, and it can be found here:

https://github.com/MethodicalAcceleratorDesign/MAD/blob/master/lib/patches/lj_intable.patch

Best,
Laurent.

--

Laurent Deniau                           http://cern.ch/mad

Accelerators Beam Physics        mad@xxxxxxx
CERN, CH-1211 Geneva 23       Tel: +41 (0) 22 767 4647










Other related posts: