X&Y values in Document

Here’s something I recently discovered,

***
((
	Document.current.mouseDownAction_

	(
		Document.current.mouseUpAction_

		{
			|doc x y modifiers buttonNumber clickCount|

			[
				\doc -> doc								// 	document instance
				,
				\x -> x
				,
				\y -> y
				,
				\mods -> modifiers						//	holding down ctrl etc....
				,
				'button#' -> buttonNumber				//	zero for left click
				,
				'click#' -> clickCount
				,
				$\n
			]

			.

			printAll
		}

		.

		mouseUpAction
	)
))

…and here’s the onset of how I intend on using it:

***
((
	Document.current.mouseDownAction_
	
	(
		Document.current.mouseUpAction_
		
		{
			|doc x y ...z| 
			
			z = 
			
			(
				z @ 0	
				
				+	
				
				z @ 1 	
			)
			
			;
			
			[
				\x : x
				
				,
				
				\y : y
				
				,
				
				\z : z
				
				,
				
				$\n
			]
			
			.
			
			printAll
			
		}
		
		.
		
		mouseUpAction
	)
))

After reading a couple of your code examples, I have to ask you: are you aware that your formatting style is rather idiosyncratic? I think you are a bit too generous with line breaks :slight_smile: I mean, putting “.” and “;” on a seperate line!? I have a very hard time reading this and I think I’m not alone.

Here’s how it would look like in a more idiomatic style (of course, it’s not the only possible way!):

(
	Document.current.mouseDownAction_(
		Document.current.mouseUpAction_ { |doc x y ...z| 
			z = (z@0 + z@1);
			[\x: x, \y: y, \z: z, $\n].printAll
		}.mouseUpAction
	)
)
4 Likes

I think those methods aren’t meant to call each other, also they don’t have the same signature and you are assigning the same function to mouseUpAction each time mouseDownAction is called. An equivalente more correct way to do the same could be:

(
a = { |doc x y ...z| [\x: x, \y: y, \z: z, $\n].printAll };
Document.current.mouseDownAction = a;
Document.current.mouseUpAction = a
)

@Spacechild1 I am very well aware. It’s the way I’ve evolved and’ve become accustomed to programming in general.

I have a very aesthetically driven approach to computer “science”, which often causes a subtle debacle in the IMO’s of the intellects I most admire.

I’m also a convert towards being vertically orientated as a programmer in general… it’s something I still resonate with as an epiphany.

A perfectly edged vertical script allows for the programmer to read it’s code without ever having to move their eyes back & forth. Reading code this way is much, much more enjoyable once you’re used to it.

The vertical spacing in between the elements of syntax allow for one to have greater ease with the mental processing of the information.

Having the dot on it’s own line by itself? Is a little extreme, I admit, and it isn’t entirely necessary… it allows for the greater amount of space to separate the concepts for the ease of one’s own interpretation.

It is far easier to keep one’s eyes fixed on the left side of the page, or left/center, while using the PgUp & PgDown keys to fly throughout the document… but I digress… I digress…

As for @lucas, another clearly talented & clever programmer I admire, but I must admit, I have no clue what you’re talking about… assigning the mouseUpAction_ first, returns the Document object after assignment, and then, calling it’s mouseUpAction will immediately return the function just defined, which is then assigned as the mouseDownAction. to the same instance of Document.

I believe that perhaps you mistook the first ( as being a { … which would perhaps explain the nature of the misconception, unless I am the one who really has it terribly wrong here, in which I must ask to please forgive me in advance…

***

It isn’t the verticality that I find an impediment to legibility – I often write e.g.

something
.method(args)
.otherMethod(args)

– rather than chaining them on one line.

It’s the nesting. Expressing flow of control by nesting means that the last thing to be done may be the first to appear in the code. At best I could see this as a way to bring the final outcome to the fore but in my own code, I find myself using variables more and nesting less, in order to present the expected sequence of events more or less in order of execution.

hjh

1 Like

@Rainer

I’m also a convert towards being vertically orientated as a programmer in general… it’s something I still resonate with as an epiphany.

For your personal projects you can, of course, use any formatting style you want. But once you expect other people to read it, please use something that at least somehow resembles one of the established styles. Writing code is also about communication.

It is far easier to keep one’s eyes fixed on the left side of the page, or left/center, while using the PgUp & PgDown keys to fly throughout the document… but I digress… I digress…

You are right that long lines can impede readability (that’s why auto-formatters enforce a line length limit), but you know, there’s some middle ground. Putting a single “+” on it’s own line, with extra line breaks above and beneath is just bizarre.

@jamshark70’s example is fine because the line breaks help to structure the code and it’s a common idiom. (In a procedural language those would be individual function calls anyway.)

1 Like
  • | - |

I believe that perhaps you mistook the first ( as being a { … which would perhaps explain the nature of the misconception, unless I am the one who really has it terribly wrong here, in which I must ask to please forgive me in advance…

Yes, that’s exactly what happened, I think because a parenthesis there had no meaning for me and I don’t have good sight. It’s valid syntax but confusing, I’m the living proof :slight_smile: You were given good advice about code as a means of communication, aesthetics is a slightly different issue but also requires some social consensus and mutual understanding. Maybe a good approach for these particular cases could be to first do it right then make it nice, maybe.

I was actually able to solve an original problem with forcing the last created Document to front using this feature.

This is sort of a script one would use in startup.scd

It also gives each document it’s own environment, which prototypes to topEnvironment while maintaining it’s own unique ~x, ~y, & ~z values.

***
Document.initAction_

{
	run
	
	(
		Routine
		
		{
			current
			
			(
				Document.current_
				
				(
					Document.allDocuments.last
				)
			)
			
			.mouseDownAction_
			
			(
				current
				
				(
					Document
				)
				
				.mouseUpAction_
				
				{
					|doc x y ...z|
					
					[
						\x : \x envirPut:
						
						(
							x
						)
						,
						
						\y : \y envirPut:
						
						(
							y
						)
						
						,
						
						\z : \z envirPut:
						
						(
							z @ 0
							
							+
							
							z @ 1
						)
						
						,
						
						$\n
					]
					
					.printAll
					
				}
				
				.mouseUpAction
			)
			
			.front
			
			.envir_
			
			(
				Environment
				
				[
					
				]
				
				.know_
				
				(
					true
				)
				
				.proto_
				
				(
					topEnvironment
				)
			)
			
			;
			
			yieldAndReset
			
			(
				1
			)
		}
	)
}

It does require a little bit of editing, to make it suitable, to one’s own preferences, I believe… there needs to be a “success” check in the yieldAndReset section, otherwise, the stream runs indefinitely, which may or may not be a problem, depending on the situation…

I’m not too strict about that – I just wrote this yesterday, in another thread:

f = { |array, windowSize = 512|
	var seq = Pseq(array, 1);
	var pad = Pn(0, windowSize);
	(
		(
			Pseries(0, Pseq([seq, pad]).squared)
			-
			Pseries(0, Pseq([pad, seq]).squared)
		)
		/ windowSize
	).sqrt
	.asStream.all;
};

… where “verticalizing” the subtraction operator highlights the similarity between the operands.

This is also moderately nested, and does feature grouping characters isolated on their own lines, like Rainer’s idiom. What is different is that here, the operators are in order: you can read this straightforwardly as “sum of squares, divided by a count (= mean), square-rooted” which tells you what is being done in what order. If this were rewritten with a bias toward prefix notation, you’d have to read “the square root of the quotient of the sum of squares and a count” and the order is less clear (though the source of the result might be more clear). In the end it’s a matter of preference; LISP prefers prefix notation as well (and I struggled with that too).

With that said, I’m less likely to engage with code on the forum if it takes extra work to understand it. We’re all busy, and all volunteering time here.

hjh

@jamshark70

I’m not too strict about that – I just wrote this yesterday, in another thread:

Yes, I shouldn’t make apodictic statements. But in your case the operands are complex subexpressions which are too long to put on a single line.

I pretty sure that 99% of readers will find

z@0 + z@1

more readable than

z @ 0

+

z @ 1

So again it’s about finding some middle ground.

And fortunately, you don’t insert line breaks after each statement :slight_smile: Line breaks are used to structure code into semantic units. If there’s a line break after each line of code, it loses it’s meaning.

BTW, if the subexpressions get too large, that’s a good place to use local variables (with meaningful names). The example above could also be written as:

f = { |array, windowSize = 512|
        var seq = Pseq(array, 1);
        var pad = Pn(0, windowSize);
        var lhs = Pseries(0, Pseq([seq, pad]).squared); // choose better name
        var rhs = Pseries(0, Pseq([pad, seq]).squared); // choose better name
        ((lhs - rhs) / windowSize).sqrt
            .asStream.all;
};

Personally, I prefer the latter, but I find your style quite readable as well!


@Rainer sorry for hijacking your thread! Won’t happen again. Just wanted to let it out somewhere.

… also misleading, because SC’s left to right order means that this would produce Point(Point(z, 0) + z, 1) and you’re much less likely to figure that out when the syntactically insignificant formatting strongly biases the reader toward a grouping that the compiler wouldn’t follow.

But perhaps that’s enough… I do find it fascinating to see an alternate take on SC syntax, though I don’t see myself adopting any of those practices.

hjh

… also misleading, because SC’s left to right order means that this would produce Point(Point(z, 0) + z, 1)

Here the @ operator is a shortcut for array indexing. (z is an array.) z@0 is the same as z[0]. To be honest, I have never used this notation because I’m so used to square brackets. And it’s easy to confuse it with Points :slight_smile:

I admit, more often than not the breaks in ubiquitous style & formatting are still in the earliest stages of discovery & practice when they arrive to the threads.

Thanks to everyone for the feedback.

I agree to an extent that giving the dot operator it’s own line is a little extreme and in a sense ultimately redundant. I’ve was being over-addicted to the whitespace as a form of eye candy.

It’s remains very promising to consider a vertical approach to the syntactical layout of computer programming.

I myself find it difficult to fully process complex ideas whilst in the necessary and all to demanding phase of still figuring out wtf is going on here, when those ideas are presented so damn closely to the next step or instruction that I’ve yet the ability to fully ascertain, my mind feels forced into the antagonistic state of being unable to swim fluently from one idea fully captured (or assimilated) into the next, and instead it feels like a great fight to stay afloat.

I suppose this is due to how speed reading is usually thought… perhaps it’s an ailment unique to my experience, and it’s something I should deal with and shut up about it.

One thing I find rather interesting, and let’s not take this in the form of an over-extended or defensive argument, because it isn’t… but after considering more than two or three times, the major complaint that @Spacechild1 has with the particular z[0] + z[1] example, and how outlandish it appears compared to what we’re used to,

I find it rather interesting, because in fact, this little part of the script is really just adding two numbers together… which is the exact format that everyone learned basic addition and arithmetic, since the first time it was ever presented to them.

z @ 0

+

z @ 1

I also find it somewhat interesting that 'a plus sign on it’s own line!` really grinds his gears more than anything, when this is, the most natural place to have a plus sign, after all!

I’m probably digging my own grave hear, because I find myself more and more on an equal level of anti-preference, the more I find myself accustomed to the ease and natural beauty of symmetry, line breaks, and the certainly “idiosyncratic” nature of my own unique flair… the more I relish my own style, the more I abhor having to read code that flows in the opposite direction.

I have to learn to be able to comprehend other styles of syntactical layout… and that mostly comes in time, with practice and ability to understand the true nature of the semantics. Which I appreciate is the root of most of James’ arguments in this area… it’s the kind of clarity that a seasoned developer would naturally argue.

I see nothing wrong with writing a statement in code vertically, but since I’m the minority, I completely understand and agree that I should tone it down a bit, for the sake of everyone here.

I must say that programming would be a lot easier if vertical orientation was adopted as a sort of major epiphany on a widespread scale… and maybe it’s just me, I was the fastest reader with 94% or higher comprehension every. single. year… when I attended school, and I took a few basic speed reading courses since then, and now it’s almost impossible to read code when stacked line by line.

@Spacechild1 made the statement somewhere, that line breaks are made to separate semantical meaning, and when they’re used everywhere, they have no meaning, but I somewhat disagree… I believe we all know that everything we do is either data or instructions, and the reason that the dot operator on a single line is borderline ridiculous, is in support of exactly this claim entirely: It makes no change to the ultimate meaning of the syntax, it is simply a gateway for a method, or a routine of instructions, to be applied to an object, and this I understand to be ( only somewhat ) asinine, as the extra line break, while unusual, surely does nothing to hurt the overall message, or make it more confusing.

To able to process the data side of the equation, the mind has to process each element of syntax separately, in the basic equation:

z @ 0

…could no less incorrectly be written vertically, with plenty of space to separate the concepts in one’s own natural flow of processing, in the form of:


z

@

0

However… if we were to continue the equation as in the original example, then we would have a problem, and I need not e,g, the atrocity of having all seven characters z @ 0 + z @ 1 exist on the their own separate platforms.

And I believe it may be (perhaps) a similar reason why @jamshark70 brought up his example, with the two lines/objects surrounding the - minus operator.

The data objects and the singleton instance of instruction are each given their own line, in classic arithmetic fashion, and while the dot operator on it’s sole line is absurd, and I while I really must agree, and make changes to the nature of things for the sake of good company, in exchange for something more predictable, such as:

\z : \z envirPut:

(
	z[ 0 ] + z[ 1 ]
)

I am also reminded of certain artistic works (vividsnow above all comes to mind) … where there is a certain atitude, of: “I really don’t give a f*** if it’s a fire burning deep in esoteric complexity”, this is how this will be… and I may have adopted something akin to this nature, overbearing when approaching it’s like ever so slightly, and I think @lucas mentioned something about ‘a mutual consensus’ with absolute precision… and sometimes, this isn’t the place for that, and we should be aware of it.

It’s late and I assume nearly all of this is TL;DR… I personally would have stopped reading miles ago, and I’d like to thank everyone here for the hijacking and the critical feedback especially… I get very annoyed by the off-topic transgressions ( I mean digressions… ;)) but I’m now realizing that the former was no one else’s but my own, and the latter was more-over a well needed attempt to lash some sense into me, and so I’d like to end all of this on a note of professional appreciation.

I have to get back to work on something that’s important to me… thanks again for everyone’s input.

TL;DR

:v:

Here’s the final version of an .initAction_ script for SC’s refined Document class.

Th implications of this will reveal a wealth of advanced & unique strategies for seamlessly integrating multiple workflows.

A signature was made recently about “assuming an exponential relation between two parameters” in terms of sound design & synthesis.

The proposed solution was to manually adjust the relation between two parameters (e.g. the attack and the release in a percussive-shaped envelope) until “the sweet spot” was found.

The fundamental hindrance with using audio programming as the foundation or interface for synthesis design is the constant demand to enter, shift, backspace, test, re-enter, delete, and dial in the numerical values of a staggering amount of individual floating point values… with the overwhelming precision of 64 point floats being the standard data type.

The notion of resolving this common obstacle by making use of one’s x/y screen coordinates is a rather novel innovation.

MouseX & MouseY must be used as audio or control rate unit generators. They are efficient, yet perhaps limited in terms of seamless integration.

Perhaps the only remaining effective routes of access to the luxury of constant stream data that a simple trackpad will provide, in addition to the classic X&Y mouse Ugens, are: The mouseUp and mouseDown instance methods, provided by the interface for class Document.

Each action method is unique to each individual Document instance, however, such behavior can be deployed ‘globally’, by putting wrapping a common action assignment within class Document's global .initAction_, and to be evaluated for each & every opened or newly created document.

Another unique feature provided by the Document class is the ability to link each document to it’s own private instance of Environment (and pushed to the global stack of Environments; available via Environment.stack, depending on preference)

In the following example, each Document’s linked environment (which is automatically linked to all code executed within the document when the document is in front / focus) is ‘prototyped’ to one’s topEnvironment (usually the current Environment used for accessing ~global_variables), and this will cause any global variables not found in the linked .envir_ to be checked for the main/default global namespace.

***
Document.initAction_

{
	AppClock.sched

	(
		1.1 ,

		{
			Document.current_

			(
				Document.allDocuments.last
			)

			.current

			.front

			.envir_

			(
				push

				(
					Environment

					[

					]

					.know_

					(
						true
					)

					.proto_

					(
						topEnvironment
					)
				)
			)

			.mouseDownAction_

			{
				|doc x y ...z| 	// z -> [ modifiers , mouseButton , clickCount ]

				Post <<*

				[
					\x : ~x = x,

					\y : ~y = y,

					\z : ~z = z@0 + z@1  // combining mod+mouseButton should still create unique #
				]

				<< $\n
			}

			.mouseUpAction_

			{
				|doc x y ...z| 

				switch
				(
					z[ 0 ]
				){
					262144 	 // hold down the ctrl key to see it's mod # 
				}{
					load		// this will execute the entire file upon ctrl+click

					(
						doc . path
					)
				}
			}
		}
	)
}




x, 170, y, 180, z, 0

Of z@0 + z@1:

So, (let me adjust the whitespace to highlight the compiler’s view of it) z @ 0 + z @ 1 is (z[0] + z)[1] then – oddly I think this will produce the desired numeric result, though inefficiently (by producing a whole new array in the addition operator and then discarding all but one of those results).

Actually I see now that this is taken from Rainer’s code block – @Rainer , check your grouping. In SC you should write explicit parens, at minimum z@0 + (z@1), or use bracket-at syntax z[0] + z[1] (where the bracket-at binds more tightly than the binary operator).

Writing it vertically will not force the compiler to see it the way you do. You can still write it vertically, but with parens. (One of the style guide recommendations I pushed for, not as an absolute rule but as an occasionally breakable suggestion, was to put spaces on either side of all binary operators, with rare exceptions such as z[i-1] where it’s a bit pedantic to insist. The inconsistent spacing in both the original vertical version and in Spacechild1’s rewrite z@0 + z@1 is visually misleading, implying grouping that doesn’t exist.)

Doesn’t the initAction take the new document as an argument? (Edit: it does – initAction.value(this); in Document:prAdd.) Then you could do:

Document.current_
(
    newDoc
);
newDoc.front ... etc

… which is still vertical but less clunky than setter_(...).getter.

hjh

In SC you should write explicit parens, at minimum z@0 + (z@1), or use bracket-at syntax z[0] + z[1] (where the bracket-at binds more tightly than the binary operator).

Wow, so @ is an alias for [] or at - but with a different precedence? Makes sense :crazy_face:

  • z.at(0) is standard method call syntax. The selector binds to the immediately preceding expression not including binary operators – in a + b.at(0), “at” applies to b, not to the result of a+b. (I.e., method calls have higher precedence than binary operators.)

  • z[0] is an alternate syntax for z.at(0), handled specially in the compiler.

  • z @ 0 is a binary operator expression which only happens to be implemented for collections as an alias for at. (As noted earlier in the thread, Object implements @ to create a Point(this, that) – so it isn’t quite right to say it’s always an alias for at.) The binary op @ follows the same precedence rule as every other binary op – left to right, requiring explicit parentheses to enforce a different grouping.

IMO @ for arrays should probably be deprecated. I can’t think of a good reason to use it, when there is already a more intuitive syntax available. EDIT: I take back the thought about deprecation – it’s been in for 18 years, no point in breaking backward compatibility now. I stand by the assertion that there’s no good reason to prefer @ for array indexing, though.

hjh

There are convenience methods for class Integer, which may simplify the process for identifying command key modifiers.

Document.current.mouseDownAction_

{
	|doc x y z|	Post <<* [x:x, y:y, z:z] << $\n;
	
	case
	
	{
		z.isShift
	}
	
	{
		/**/
	}
	
	{
		z.isCtrl
	}
	
	{
		/**/
	}
	
	{
		z.isAlt
	}
	
	{
		/**/
	}
}