Alternative to "do"

Got a LiveCode personal license? Are you a beginner, hobbyist or educator that's new to LiveCode? This forum is the place to go for help getting started. Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller

Post Reply
dhurtt
Posts: 42
Joined: Sat Nov 09, 2013 7:37 pm

Alternative to "do"

Post by dhurtt » Sat Nov 09, 2013 8:05 pm

I am looking for an alternative to using the "do" command. What I have works, but I just want to see if there is a more efficient way of doing my task that I am not aware of, as I understand that "do" has to compile on the fly, so may be slower. What I am doing is something like this:

Code: Select all

function a x, y
  # return something
end a

function b x, y
  # return something
end b

function c x, y
  # return something
end c

function getFunction n, m
  if someCondition then
    return "a"
  else if someOtherCondition then
    return "b"
  else
    return "c"
  end if
end getFunction

on mouseup
  # some code to get n, m, x, and y ...
  put getFunction(n, m) into myFunction
  do "put" && myFunction & "(x, y) into someVariable"
  # do something with someVariable
end mouseup
I have noticed that I can call a variable and it will find the command of that name, but it does not seem to work with functions. Maybe I am doing something wrong syntactically? This works:

Code: Select all

command a
  answer "a"
end a

command b
  answer "b"
end b

command aorb
  answer question "a or b?" with "a" or "b"
  call it
end aorb
But this does not:

Code: Select all

function a x, y
   return "x"
end a

function b x, y
   return "y"
end b

command aorb
   answer question "a or b?" with "a" or "b"
   call it(1, 2)
   answer it
end aorb
It complains that it cannot find the message handler. Walking through the debugger, "it" contains the proper value. So it seems that "call" cannot be used with functions, only commands?

Thanks in advance,

Dale

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10331
Joined: Wed May 06, 2009 2:28 pm

Re: Alternative to "do"

Post by dunbarx » Sat Nov 09, 2013 11:09 pm

Hi.

These things do get convoluted. For your last code thingie, does this help?

Code: Select all

function a x, y
   return "x"
end a

function b x, y
   return "y"
end b

on mouseUp
   answer question "a or b?" with "a" or "b"
 get "get" &&  it & "(1, 2)" 
do it
answer it
end mouseUp
At least this is syntactically correct, but is a house of cards.

And just for fun:

Code: Select all

on mouseUp
   answer question "a or b?" with "a" or "b"
 answer "do get get" &&  it & "(1, 2)"
end mouseUp
Craig Newman

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10052
Joined: Sat Apr 08, 2006 7:05 am
Contact:

Re: Alternative to "do"

Post by FourthWorld » Sat Nov 09, 2013 11:34 pm

It may seem awfully pedestrian, but have you considered an "if" or "case" block?
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

dhurtt
Posts: 42
Joined: Sat Nov 09, 2013 7:37 pm

Re: Alternative to "do"

Post by dhurtt » Sun Nov 10, 2013 12:39 am

FourthWorld wrote:It may seem awfully pedestrian, but have you considered an "if" or "case" block?
Yes I have. These are simplified examples, not the real code. My functions are called based on the result of mathematical calculations; they determine the next step to take. They are called from multiple points in the code, which is why they are pulled out into separate functions. Embedding the calculations used to determine which function to call in multiple handlers sprinkled throughout the code is very bad practice.

For example, I have used a command, "aorb", as the "calculation" of which function to call, "a" or "b". Imagine I do as you suggest and pull out the code inside "aorb" and proliferate it in four different spots. Now imagine that I need to change the number of functions that are called; I now have a function "c". Or I need to change the way in which the functions are called (maybe add a new parameter). You start to see how it gets ugly fast.

But I did post this on the beginner's forum, so thanks for asking. You never know when it would apply.

"do" seems like it is a cousin to Javascript's "eval", as both have to evaluate strings and come up with machine instructions on the fly, thus it is "expensive". I am simply trying to find out if there was another way, like with the "call" command, to call a function whose name is within a variable. I suspect that "get" also functions in the same way as "do" (i.e. is just as expensive) as it evaluates the string according to the API documentation. I now wonder whether "call" is doing the same?

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10052
Joined: Sat Apr 08, 2006 7:05 am
Contact:

Re: Alternative to "do"

Post by FourthWorld » Sun Nov 10, 2013 2:19 am

Well, I was only half-right: while case is faster than do in some scenarios, dispatch is fastest.

Of course the speed of case will depend on the number of cases, but given this script in a button:

Code: Select all

on mouseUp
   put "foo" into tCmd
   put 100000 into N
   --
   -- Test 1: dispatch
   put the millisecs into t
   repeat N
      dispatch tCmd
   end repeat
   put the millisecs - t into t1
   --
   -- Test 2: do
   put the millisecs into t
   repeat N
      do tCmd
   end repeat
   put the millisecs - t into t2
   --
   -- Test 3: case
   put "foo"& 10 into tCmd
   put the millisecs into t
   repeat N
      switch tCmd
         case "foo1"
            foo1
            break
         case "foo2"
            foo2
            break
         case "foo3"
            foo3
            break
         case "foo4"
            foo4
            break
         case "foo5"
            foo5
            break
         case "foo6"
            foo6
            break
         case "foo7"
            foo7
            break
         case "foo8"
            foo8
            break
         case "foo9"
            foo9
            break
         case "foo10"
            foo10
            break
      end switch
   end repeat
   put the millisecs - t into t3
   --
   -- Test 4: call
   put the millisecs into t
   repeat N
      call tCmd
   end repeat
   put the millisecs - t into t4
   
   put "dispatch: "& t1 &"  do: "& t2 &"  case: "& t3 &"  call: "& t4
end mouseUp
And this script in the card:

Code: Select all

on foo
   get 1+1
end foo


on foo1
   get 1+1
end foo1

on foo2
   get 1+1
end foo2

on foo3
   get 1+1
end foo3

on foo4
   get 1+1
end foo4

on foo5
   get 1+1
end foo5

on foo6
   get 1+1
end foo6

on foo7
   get 1+1
end foo7

on foo8
   get 1+1
end foo8

on foo9
   get 1+1
end foo9

on foo10
   get 1+1
end foo10

Here are the results:
dispatch: 277 do: 438 case: 336 call: 389

While confirming the boost with case was mildly interesting, the benefits of dispatch are so overwhelming that it doesn't matter, and dispatch is much simpler to use than writing a tedious case block.

If you do a lot of benchmarking in LiveCode there may be some things here of interest:

Benchmarking Performance in LiveCode
http://livecodejournal.com/tutorials/be ... vtalk.html
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

dhurtt
Posts: 42
Joined: Sat Nov 09, 2013 7:37 pm

Re: Alternative to "do"

Post by dhurtt » Sun Nov 10, 2013 3:12 am

"dispatch" appears to be the command I was looking for. Thanks!

Post Reply