Jump to content
Claris Engage 2025 - March 25-26 Austin Texas ×

This topic is 6365 days old. Please don't post here. Open a new topic instead.

Recommended Posts

Posted (edited)

This file implements a set of custom functions for creating and operating on multi-dimensional matrixes (ie, arrays). The matrixes are stored in global variables, using the evaluate method to simulate a "pointer" type within fileMaker.

Even if you aren't interested in multi-dimensional arrays you should probably take a gander at this, I think the concepts here open some doors to more complex data structures.

If you are interested in matrixes, you'll find some useful custom functions here, a tutorial on how to use them, with live examples of them working as you move through the tutorial.

The user-level functions implemented include:

  - CreateMatrix( "M"; "3x5" ) - returns a reference to a 3x5 matrix storing all empty values.

  - MatrixGet( ; List( 1; 0 ) ) - access the data stored at index (1,0).

  - MatrixSet( ; List( 0; 0 ) ) - sets the data at index (0,0), types are maintained, so the matrix is suitable for storing all types (dates, containers, etc).

  - DeleteMatrix( ) - deletes the matrix, clearing out all the global variables it used.

  - MatrixApply( ; ) - apply a function to each element of the array.

And many more fun methods, take a look at it.

This idea came to me while we were discussing repeating global variables here.

matrixVars.fp7.zip

matrixVarsV2.fp7.zip

Edited by Guest
Updated file.
Posted

That's actually quite awesome, my only concern is that these are all CF's, and CF's don't copy that well!!

Posted

You know... i read that comment about an hour and a half ago, and I'm like what's the matrix got to do with this.

Then i read it again like half an hour ago, and still nothing...

And then it finally occurred to me lol.

Posted

By the way, here is a function that gets a value equivalent in a matrix. (not recursive)

Better look at the file to understand what I mean.

This was originally done by Ugo. Can't remember if I even had to adapt it.

Matrix_GetEquiv.fp7.zip

Posted

I understood Vaughan's comment right away. Understanding the two files? Maybe in the next millennium.

Lee

:o

Posted (edited)

I think the original point I was trying to demonstrate had gotten lost in the implemenation complexity of the matrix.

What I wanted to show was that by using a repeating global variable, a simple data structure can be simulated by placing data at fixed offsets from the original variable. A set of custom functions that can operate on this repeating variable makes it roughly equivalent of an object-oriented language (minus any type checking).

Here is a much smaller example, that implements a queue, the methods are:

  queueRef :P= CreateQueue( )

  EnQueue( queueRef, value )

  value := DeQueue( queueRef, value )

  QueueCount( queueRef )

  DeleteQueue( queueRef )

The call:

  CreateQueue( "Q" )

creates and returns a queue object (conceptually, a list of values, the first one you put in is the first one you get back when you remove one - a FIFO queue). This queue object is really just a string that holds a global variable, in this case it would be "$$Q", which can be used by the other methods to access the storage for the object (via Evaluate to dynamically select a repetition of it).

For a queue, we need to know how many values are stored and at what indexes. This can be done by storing the index of the first value (front) in the queue at $$Q[-2], and the index of the next empty place to put an inserted value in $$Q[-3]. The CreateQueue call sets both $$Q[-2] and $$Q[-3] to zero, and when these two indexes are the same, the queue will be considered to be empty. So, after the create, the queue variable currently look likes:

  $$Q[-3] = 0

  $$Q[-2] = 0

  $$Q[0] = ""

The EnQueue method inserts a value into the queue by placing it at $$Q[ $$Q[-3] ], and incrementing $$Q[-3] so for that the next inserted value knows where to go. So, calling:

  EnQueue( "$$Q", "hello" )

  EnQueue( "$$Q", 3.14 )

changes our state to:

  $$Q[-3] = 2

  $$Q[-2] = 0

  $$Q[0] = "hello"

  $$Q[1] = 3.14

  $$Q[2] = ""

Calling DeQueue removes an item (if the queue is not empty) from the front of the queue, which is pointed to by $$Q[-2], and incrementing that index. It also sets the variable at $$Q[ $$Q[-2] ] back to empty after it grabs its value to avoid leaving garbage in memory. So, after the call:

  DeQueue( "$$Q" ) // this call will return "hello", the first item in the queue

our state will be:

  $$Q[-3] = 2

  $$Q[-2] = 1

  $$Q[0] = ""

  $$Q[1] = 3.14

  $$Q[2] = ""

Finally, the DeleteQueue method just clears out these repetitions, which can be used when the queue is no longer needed.

Now, the point isn't that this is a great queue structure, but rather that this technique can be used to implement a wide variety of data structures.

[i hope this is clearer than the original Matrix, which uses this concept also, but extends it further by creating sub-matrixes that are also Matrix objects to be the elements stored inside a multi-dimensional matrix.]

Queues.fp7.zip

Edited by Guest
Posted

Thanks for your post.

One one hand, I re-read the whole thread and finally understood Vaughan's comment (how could I be so blind ?). And on the other hand, my plan was : cook a nice dinner, maybe watch a movie or read a book, then go to bed without thinking of databases. And this plan is now completely ruined. Thank you Shawn. I hate you :P

No really : thank you. This is MOST interesting, but I will need some time to understand everything.

Posted

I am curious what actually happens when a variable is "deleted". Is it really purged from memory? It is perhaps worth noting that an expression referring to an undefined variable name does not result in error, and all of the following evaluate to TRUE:

IsEmpty ( $undefined )

IsValid ( $undefined )

IsValidExpression ( "$undefined" )

Posted

Yes, the global (and script local) variables don't store empty values, they are just removed, since the return value for a variable that isn't defined is empty anyway.

Local variables inside calculations do continue to exist even when empty, since they are really a different kind of thing - they are more like the custom function parameters.

Posted

Thanks. Those are very interesting demonstrations. Even if it's hard to think of opportunities for implementation, there's a lot to learn from them.

Posted (edited)

Well, I've tried to come up with a more compelling example that someone might actually find useful.

What I came up with is a date/time formatter, implemented using a similar technique as these objects.

See:

   Date Formatter

Edited by Guest
Fix url
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.