The Shadow Posted June 14, 2007 Posted June 14, 2007 (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 June 16, 2007 by Guest Updated file.
Genx Posted June 14, 2007 Posted June 14, 2007 That's actually quite awesome, my only concern is that these are all CF's, and CF's don't copy that well!!
Genx Posted June 14, 2007 Posted June 14, 2007 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.
fabriceN Posted June 14, 2007 Posted June 14, 2007 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
Lee Smith Posted June 14, 2007 Posted June 14, 2007 I understood Vaughan's comment right away. Understanding the two files? Maybe in the next millennium. Lee :o
The Shadow Posted June 17, 2007 Author Posted June 17, 2007 (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 = 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 June 17, 2007 by Guest
fabriceN Posted June 17, 2007 Posted June 17, 2007 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 No really : thank you. This is MOST interesting, but I will need some time to understand everything.
comment Posted June 17, 2007 Posted June 17, 2007 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" )
The Shadow Posted June 17, 2007 Author Posted June 17, 2007 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.
comment Posted June 17, 2007 Posted June 17, 2007 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.
The Shadow Posted June 23, 2007 Author Posted June 23, 2007 (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 June 23, 2007 by Guest Fix url
Recommended Posts