<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Passing messages to &amp;quot;this&amp;quot; within class definition in Discussions</title>
    <link>https://community.jmp.com/t5/Discussions/Passing-messages-to-quot-this-quot-within-class-definition/m-p/641421#M83854</link>
    <description>&lt;P&gt;I keep forgetting that while JSL borrows from the best (in this case &lt;A href="https://stackoverflow.com/questions/42498438/whats-so-special-about-message-passing-in-smalltalk" target="_self"&gt;message passing in smalltalk&lt;/A&gt;), it never quite captures what was special about the original.&lt;/P&gt;</description>
    <pubDate>Mon, 12 Jun 2023 14:02:17 GMT</pubDate>
    <dc:creator>KevW</dc:creator>
    <dc:date>2023-06-12T14:02:17Z</dc:date>
    <item>
      <title>Passing messages to "this" within class definition</title>
      <link>https://community.jmp.com/t5/Discussions/Passing-messages-to-quot-this-quot-within-class-definition/m-p/639003#M83685</link>
      <description>&lt;P&gt;Is it possible to pass a message to the instance of a class from within a method?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Here is an example of what I am trying to do:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-jsl"&gt;Define Class(
	"example",
	x=1;
	test = Method( {name, method},
		&amp;lt;&amp;lt; Insert(name, method);
	);
	
);

t = New Object( example());
// This fails to insert the blah method
t:test("blah", Method({y}, show("Blah " || char(x) || char(y))));
t:blah(6);

//This succeeds in inserting and calling the blah method
t &amp;lt;&amp;lt; Insert("blah", Method({y}, show("Blah " || char(x) || char(y))));
t:blah(6);&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;I suspected that I might need to explicitly write "this &amp;lt;&amp;lt; Insert", but that yields a different error:&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-jsl"&gt;Define Class(
	"example",
	x=1;
	test = Method( {name, method},
		&lt;STRONG&gt;this &amp;lt;&amp;lt; Insert(name, method);&lt;/STRONG&gt;
	);
	
);

t = New Object( example());

// This fails because "send expects scriptable object"
t:test("blah", Method({y}, show("Blah " || char(x) || char(y));));
t:blah(6);&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;I also considered explicitly calling Send (fails to add the method) and this:Send (fails to resolve the name Send).&lt;/P&gt;&lt;P&gt;I also considered directly calling this:Insert (fails to resolve the name Insert) and Insert (successfully adds the blah method, but fails to correctly plumb the calling mechanism, so no arguments get passed into the method).&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Motivation:&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;I am doing this because I am trying to automatically create getter- and setter- methods for a list of class properties.&amp;nbsp; Ideally, I will be able to do the following:&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-jsl"&gt;Define Class(
	"example",
	_init_ = Method( {assocArray},
		For Each({property, updateMethod}, assocArray,
			Insert(key, Eval Expr(Method({value}, TrySetProperty(Expr(property), value, Expr(updateMethod)))));
		);
	);
	
	TrySetProperty=Method({parameter, value, expressionIfChanged},
        match(value,
            .,                                  ., 	//Do nothing if missing value
            this &amp;lt;&amp;lt; Get Value(parameter),       ., 	//Do nothing if unchanged value
            this &amp;lt;&amp;lt; Insert(parameter, value);      	//Otherwise update the value 
            Eval(expressionIfChanged);				//and eval the expression
        );
    );
	
);

properties = Associative Array({{"prop1", Expr(ThingToDoOnUpdate1)},{"prop2", Expr(ThingToDoOnUpdate2)}});
t = New Object( example(properties));&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 09 Jun 2023 16:11:23 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/Passing-messages-to-quot-this-quot-within-class-definition/m-p/639003#M83685</guid>
      <dc:creator>KevW</dc:creator>
      <dc:date>2023-06-09T16:11:23Z</dc:date>
    </item>
    <item>
      <title>Re: Passing messages to "this" within class definition</title>
      <link>https://community.jmp.com/t5/Discussions/Passing-messages-to-quot-this-quot-within-class-definition/m-p/639039#M83687</link>
      <description>&lt;P&gt;By default JMP doesn't provide nice ways to query the pseudo-namespaces directly (whether that's window, this, box, etc.,).&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;For classes, you might think about creating a wrapper for constructing classes -- that wrapper can then create the instance generator function, and during that instance generation, you can give the class a circular-reference (note that this can lead to memory leaks) -- ensure that you create a tracking system and provide / call a deleter method when the class should be deleted to remove the circular references and such.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Here's an example:&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-jsl"&gt;Names Default to Here( 1 );
New Namespace( "class" );

class:Get Init Args = Function( {_class},
	{Default Local},
	For( i = 1, i &amp;lt;= N Items( _class ), i++,
		If( Head Name( Arg( _class, i ) ) == "Glue",
			For( j = 1, j &amp;lt;= N Arg( Arg( _class, i ) ), j++,
				If( As Name( Head Name( Arg( Arg( Arg( _class, i ), j ), 1 ) ) ) == As Name( "_create_" ),
					Return( Arg( Arg( Arg( Arg( _class, i ), j ), 2 ), 1 ) )
				)
			)
		)
	);
	Return( {} )
);

class:Define Class = Function( {_class},
	{Default Local},
	class = Expr( Define Class() );
	Summation( i = 1, N Arg( _class ),
		Insert Into( class, Arg( _class, i ) )
	);
	init args = class:Get Init Args( _class );
	init redirects = Expr( __cl:_create_() );
	Summation( i = 1, N Items( init args ),
		If( Head Name( Arg( init args, i ) ) == "Assign",
			Insert Into( init redirects, Eval Expr( Name Expr( Expr( Arg( Arg( init args, i ), 1 ) ) ) ) )
		,
			Insert Into( init redirects, Eval Expr( Name Expr( Expr( Arg( init args, i ) ) ) ) )
		)
	);
	Eval( class );
	ns = Namespace( "class" );
	Eval( Substitute( Expr(
		ns[__class__] = Function( __args__,
			{__cl = New Object( __class__ )},
			__cl:self = __cl;
			__class_call__;
			__cl
		)
	),
		Expr( __class__ ), Arg( _class, 1 ),
		Expr( __args__ ), init args,
		Expr( __class_call__ ), Name Expr( init redirects )
	) );
	0
);

class:Define Class({
	"example",
	_init_ = Method( {}, 1 );
	_create_ = Method( {assocArray},
		For Each( {{key, setter}, _}, assocArray,
			self &amp;lt;&amp;lt; Insert( key, Eval Expr( Method( {value}, self:TrySetProperty( Expr( key ), value, Expr( setter ) ) ) ) )
		)
	);
	Try Set Property = Method( {parameter, value, expression If Changed},
        Match( value,
            .,                                  ., 	//Do nothing if missing value
        ,  
            self[parameter],       .	//Do nothing if unchanged value
        ,
            self[paremeter] = value;      	//Otherwise update the value 
            Eval( expression If Changed );				//and eval the expression
        );
    );
    show = Function( {name},
    	show( name )
    )
});

//show( namespace( "class" ) );

cls = class:example( ["A" =&amp;gt; expr( self:show( "EXPLETIVE" ) ), "B" =&amp;gt; Expr( thing 2 )] );

show( cls &amp;lt;&amp;lt; get keys );&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;Note though that JMP classes are just glorified namespaces with functions attached (namespaces where the attached functions are aware of what namespace they're in).&amp;nbsp; You can do something quite similar with just regular namespaces and meta-programming.&amp;nbsp; And with the regular namespaces JMP won't throw superfluous errors around about not being able to access class methods within functions and whatnot.&lt;/P&gt;</description>
      <pubDate>Tue, 06 Jun 2023 01:52:34 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/Passing-messages-to-quot-this-quot-within-class-definition/m-p/639039#M83687</guid>
      <dc:creator>ErraticAttack</dc:creator>
      <dc:date>2023-06-06T01:52:34Z</dc:date>
    </item>
    <item>
      <title>Re: Passing messages to "this" within class definition</title>
      <link>https://community.jmp.com/t5/Discussions/Passing-messages-to-quot-this-quot-within-class-definition/m-p/640965#M83818</link>
      <description>&lt;P&gt;This does seem to be the kind of workaround JSL forces you to do.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;There is a parody programming language called "DreamBerd" which makes fun of programming paradigms.&amp;nbsp; This workaround is very similar to how the parody language handles classes, but manages to be even more complex.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;(Not saying this is your fault, its just a consequence of the limitations in JSL).&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;A href="https://github.com/TodePond/DreamBerd" target="_blank" rel="noopener"&gt;https://github.com/TodePond/DreamBerd&lt;/A&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;BLOCKQUOTE&gt;&lt;HR /&gt;Classes&lt;P&gt;You can make classes, but you can only ever make one instance of them. This shouldn't affect how most object-oriented programmers work.&lt;/P&gt;&lt;DIV class=""&gt;&lt;PRE&gt;&lt;SPAN class=""&gt;class&lt;/SPAN&gt; &lt;SPAN class=""&gt;Player&lt;/SPAN&gt; {
   &lt;SPAN class=""&gt;const&lt;/SPAN&gt; &lt;SPAN class=""&gt;var&lt;/SPAN&gt; &lt;SPAN class=""&gt;health&lt;/SPAN&gt; = &lt;SPAN class=""&gt;10&lt;/SPAN&gt;!
}

&lt;SPAN class=""&gt;const&lt;/SPAN&gt; &lt;SPAN class=""&gt;var&lt;/SPAN&gt; &lt;SPAN class=""&gt;player1&lt;/SPAN&gt; = &lt;SPAN class=""&gt;new&lt;/SPAN&gt; &lt;SPAN class=""&gt;Player&lt;/SPAN&gt;()!
&lt;SPAN class=""&gt;const&lt;/SPAN&gt; &lt;SPAN class=""&gt;var&lt;/SPAN&gt; &lt;SPAN class=""&gt;player2&lt;/SPAN&gt; = &lt;SPAN class=""&gt;new&lt;/SPAN&gt; &lt;SPAN class=""&gt;Player&lt;/SPAN&gt;()! &lt;SPAN class=""&gt;//Error: Can't have more than one 'Player' instance!&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/DIV&gt;&lt;P&gt;This is how you could do this:&lt;/P&gt;&lt;DIV class=""&gt;&lt;PRE&gt;&lt;SPAN class=""&gt;class&lt;/SPAN&gt; &lt;SPAN class=""&gt;PlayerMaker&lt;/SPAN&gt; {
   &lt;SPAN class=""&gt;function&lt;/SPAN&gt; &lt;SPAN class=""&gt;makePlayer&lt;/SPAN&gt;() =&amp;gt; {
      &lt;SPAN class=""&gt;class&lt;/SPAN&gt; &lt;SPAN class=""&gt;Player&lt;/SPAN&gt; {
         &lt;SPAN class=""&gt;const&lt;/SPAN&gt; &lt;SPAN class=""&gt;var&lt;/SPAN&gt; &lt;SPAN class=""&gt;health&lt;/SPAN&gt; = &lt;SPAN class=""&gt;10&lt;/SPAN&gt;!
      }
      &lt;SPAN class=""&gt;const&lt;/SPAN&gt; &lt;SPAN class=""&gt;const&lt;/SPAN&gt; &lt;SPAN class=""&gt;player&lt;/SPAN&gt; = &lt;SPAN class=""&gt;new&lt;/SPAN&gt; &lt;SPAN class=""&gt;Player&lt;/SPAN&gt;()!
      &lt;SPAN class=""&gt;return&lt;/SPAN&gt; &lt;SPAN class=""&gt;player&lt;/SPAN&gt;!
   }
}

&lt;SPAN class=""&gt;const&lt;/SPAN&gt; &lt;SPAN class=""&gt;const&lt;/SPAN&gt; &lt;SPAN class=""&gt;playerMaker&lt;/SPAN&gt; = &lt;SPAN class=""&gt;new&lt;/SPAN&gt; &lt;SPAN class=""&gt;PlayerMaker&lt;/SPAN&gt;()!
&lt;SPAN class=""&gt;const&lt;/SPAN&gt; &lt;SPAN class=""&gt;var&lt;/SPAN&gt; &lt;SPAN class=""&gt;player1&lt;/SPAN&gt; = &lt;SPAN class=""&gt;playerMaker&lt;/SPAN&gt;.&lt;SPAN class=""&gt;makePlayer&lt;/SPAN&gt;()!
&lt;SPAN class=""&gt;const&lt;/SPAN&gt; &lt;SPAN class=""&gt;var&lt;/SPAN&gt; &lt;SPAN class=""&gt;player2&lt;/SPAN&gt; = &lt;SPAN class=""&gt;playerMaker&lt;/SPAN&gt;.&lt;SPAN class=""&gt;makePlayer&lt;/SPAN&gt;()!&lt;/PRE&gt;&lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;</description>
      <pubDate>Fri, 09 Jun 2023 19:10:14 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/Passing-messages-to-quot-this-quot-within-class-definition/m-p/640965#M83818</guid>
      <dc:creator>KevW</dc:creator>
      <dc:date>2023-06-09T19:10:14Z</dc:date>
    </item>
    <item>
      <title>Re: Passing messages to "this" within class definition</title>
      <link>https://community.jmp.com/t5/Discussions/Passing-messages-to-quot-this-quot-within-class-definition/m-p/641002#M83823</link>
      <description>&lt;P&gt;I think this could be handled better with custom message passing, but I can't really find any documentation about how to actually do that.&amp;nbsp; As far as I can tell, there is no info about implementing your own messages.&lt;/P&gt;</description>
      <pubDate>Fri, 09 Jun 2023 19:48:10 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/Passing-messages-to-quot-this-quot-within-class-definition/m-p/641002#M83823</guid>
      <dc:creator>KevW</dc:creator>
      <dc:date>2023-06-09T19:48:10Z</dc:date>
    </item>
    <item>
      <title>Re: Passing messages to "this" within class definition</title>
      <link>https://community.jmp.com/t5/Discussions/Passing-messages-to-quot-this-quot-within-class-definition/m-p/641045#M83826</link>
      <description>&lt;P&gt;Messages just call methods for classes -- technically you can't call a function with arguments via a message, but since methods in JSL classes are expressions, the result of the message call is a callable function.&amp;nbsp; For all intents and purposes, you can just call class method via a message.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Notice the line&amp;nbsp;&lt;CODE class=" language-jsl"&gt;Show( clx &amp;lt;&amp;lt; Add( cly ) );&lt;/CODE&gt; calling the &lt;CODE class=" language-jsl"&gt;Add&lt;/CODE&gt; method via a message.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-jsl"&gt;Names Default To Here( 1 );
Define Class(
	"complex",
	real = 0;
	imag = 0;
	_init_ = Method( {a, b},
		real = a;
		imag = b;
	);
	Add = Method( {y},
	PRINT( "ADDING" );
		New Object( complex( real + y:real, imag + y:imag ) )
	);
	Sub = Method( {y},
		New Object( complex( real - y:real, imag - y:imag ) )
	);
	Mul = Method( {y},
		New Object( complex( real * y:real - imag * y:imag, imag * y:real + real * y:imag ) )
	);
	Div = Method( {y},
		t = New Object( complex( 0, 0 ) );
		mag2 = y:Magsq();
		t:real = real * y:real + imag * y:imag;
		t:imag = imag * y:real + real * y:imag;
		t:real = t:real / mag2;
		t:imag = t:imag / mag2;
		t;
	);
	Magsq = Method( {},
		real * real + imag * imag
	);
	Mag = Method( {},
		Sqrt( real * real + imag * imag )
	);
	_to string_ = Method( {},
		Char( real ) || " + " || Char( imag ) || "i"
	);
	_show_ = _to string_;
);
clx = New Object( complex( 1, 2 ) );
cly = New Object( complex( 2, 3 ) );

Show( clx &amp;lt;&amp;lt; Add( cly ) );

clx &amp;lt;&amp;lt; Delete;
cly &amp;lt;&amp;lt; Delete;
Delete Classes( "complex" );&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Sat, 10 Jun 2023 11:27:04 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/Passing-messages-to-quot-this-quot-within-class-definition/m-p/641045#M83826</guid>
      <dc:creator>ErraticAttack</dc:creator>
      <dc:date>2023-06-10T11:27:04Z</dc:date>
    </item>
    <item>
      <title>Re: Passing messages to "this" within class definition</title>
      <link>https://community.jmp.com/t5/Discussions/Passing-messages-to-quot-this-quot-within-class-definition/m-p/641421#M83854</link>
      <description>&lt;P&gt;I keep forgetting that while JSL borrows from the best (in this case &lt;A href="https://stackoverflow.com/questions/42498438/whats-so-special-about-message-passing-in-smalltalk" target="_self"&gt;message passing in smalltalk&lt;/A&gt;), it never quite captures what was special about the original.&lt;/P&gt;</description>
      <pubDate>Mon, 12 Jun 2023 14:02:17 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/Passing-messages-to-quot-this-quot-within-class-definition/m-p/641421#M83854</guid>
      <dc:creator>KevW</dc:creator>
      <dc:date>2023-06-12T14:02:17Z</dc:date>
    </item>
  </channel>
</rss>

