• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: [FYI] more sdef-based library stupidity
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [FYI] more sdef-based library stupidity


  • Subject: Re: [FYI] more sdef-based library stupidity
  • From: has <email@hidden>
  • Date: Fri, 03 Jun 2016 19:21:32 +0100

Shane Stanley wrote:

> > On 3 Jun 2016, at 6:33 PM, has <email@hidden> wrote:
> >
> > do you understand exactly what AS is doing here and why?
>
> I was tempted to ask you the same question. But then you gave me the answer:
>
> > I was slightly off-target
>
> if you mean wrong, yes.
Half wrong. I identified the right location, but my first hypothesis to the cause was wrong. It fit (deferred evaluation occuring in the wrong context would produce the same result), but then I came up with a more parsimonious explanation: evaluation is eager (as is normal for Algol-y languages, right-hand Boolean operands excepted), but a keyword-based command redefines the default target prior to its parameters being evaluated. Which is basically how scientific inquiry works: being wrong, realizing you're wrong, and working your ass off to become less wrong over time.


> Messages are dispatched to the direct parameter by default.

Which is true, but actually doesn't have anything to do with what's going on here at all, so as an explanation is actually more wrong than even my first attempt. Humility 101.> So here's a lib script:
>
> use scripting additions
> use framework "Foundation"
> use framework "AppKit"
>
> on some fancy command x
>     set thePath to POSIX path of x
> set aURL to current application's class "NSURL"'s fileURLWithPath:thePath > current application's NSWorkspace's sharedWorkspace()'s activateFileViewerSelectingURLs:{aURL}
> end some fancy command
>
> And calling it like this fails:
>
> use script "Hysteria"
>
> some fancy command someLocalHandler()
>
> on someLocalHandler()
>     return "/" as POSIX file
> end someLocalHandler
>
> The error says something like "«script "Untitled"» doesn’t understand the “someLocalHandler” message." but the offending object is in fact the library. That is correct, in that «script "Untitled"» is referring to your loaded Hysteria.scpt library.


> This also fails the same way:
>
> tell script "Hysteria"
>     some fancy command someLocalHandler()
> end tell
>
> on someLocalHandler()
>     return "/" as POSIX file
> end someLocalHandler
That one I would expect to fail though, because `someLocalHandler()` is enclosed in a `tell` block that explicitly declares the default target for ALL commands within that block. However, a `use` block is NOT a `tell` block: it does NOT set the default target for commands within the script. If it did, you wouldn't be able to have more than one `use` statement per script, which obviously you can, because this works absolutely fine (as long as you don't globally use terms that are defined by more than one of the used dictionaries):

use script "TextEdit"
use script "Finder"
use script "Hysteria"
...

Thus the mechanism by which messages are dispatched to script and application objects imported via `use` is completely unrelated to the mechanism by which `tell ...` blocks or `property parent : ...` statements declare a default target object or delegate for commands sent within that scope. Thus any hypothesis of the observed behavior that invokes either feature is straight-up wrong. There's actually an extensible dispatch table somewhere in the interpreter to which runtime-imported commands are added, so that handlers imported via `use` will handle those commands, completely ignoring the target object specified by an enclosing `tell` block:

use script "Text"

tell application "Finder"
    set theList to name of every folder of home
join text theList -- `join list` is sent *directly* to Text library, not Finder app
end tell

Like I say, nothing to do with default/tell targets at all.


I believe that's where Yvan's reasoning was coming unstuck. Basically, like 99.99% of ASers he understands the language up to a point, which is enough to produce a script that usually/mostly works, then beyond that point he has a lookup table of magical incantations to apply iteratively to the bits that don't until they do: "1. try wrapping in parentheses and see if it works now", "2. try adding a `my` prefix and see if it works now", "3. try adding a `get` prefix…", and so on.


> This works:
>
> use script "Hysteria"
>
> someLocalHandler()
> some fancy command result
>
> on someLocalHandler()
>     return "/" as POSIX file
> end someLocalHandler
>
> This script also fails:
>
> use application "Finder"
>
> reveal someLocalHandler()
>
> on someLocalHandler()
>     return "/" as POSIX file
> end someLocalHandler


Repeating what we've already said.


> As does this:
>
> tell application "Finder"
>     reveal someLocalHandler()
> end tell
>
> on someLocalHandler()
>     return "/" as POSIX file
> end someLocalHandler
>
> But not this:
>
> use application "Finder"
>
> someLocalHandler()
> reveal result
>
> on someLocalHandler()
>     return "/" as POSIX file
> end someLocalHandler


Ditto.


> Of course most users already knew what was going to happen with the last three. And I'd wager most of them would expect something similar to happen when addressing script libraries that use terminology, which, surprise, surprise, is what happens.


WRONG! Users expect it when an enclosing `tell` block is involved, NOT when a global `use` statement appears. Again, you seem to be confusing:

    use application "Finder"

and:

    use script "Hysteria"

for:

    property parent : application "Finder"

and:

    property parent : script "Hysteria"

The former inject handlers into the global namespace, so that commands intended for those handlers are sent directly to them, bypassing all the normal, traditional dispatch mechanisms and rules of pre-10.9 AppleScript. The latter changes the delegate for the entire script so that commands not directed to external objects via `tell` or handled by the script itself will be routed to that delegate object to see if it can handle them. I think that's what you're confusing here, thus while my original hypothesis was half-wrong, yours is actually doubly-wrong because it's now wrong on two different levels, and you're putting those two wrongs together to give you the explanation you want, rather than the explanation that actually fits ALL the evidence.



> So put your expectations aside for a moment, and tell me exactly how this squares with your statement:
>
> > This is very bad for users: you cannot teach them that the language Works This Way and then have it magically turn around and do something completely different instead with no indication, explanation, or justification why. It violates their whole mental model of how the system works; confuses, angers, and frustrates the hell out of them; and consumes a ton of their time and energy figuring out for themselves precisely how, where, and why it isn't doing *what they're damn well telling it to do* but instead doing something else entirely
>
> Now I know there are lots of frustrating inconsistencies in AppleScript, but I'm damned if I can see how the average scripter will see this as such a case.

Let me repeat, because this is super-important: "Importing handlers via `use` ensures commands intended for those handlers are sent DIRECTLY to them." Thus, `some fancy command` is being dispatched DIRECTLY to script "Hysteria", completely ignoring all enclosing tell blocks and parent delegates, and in that respect the `use`/library system is working *exactly* as intended and documented. Oh, and it also completely ignores the direct parameter, except where that parameter is an object that can handle messages (e.g. script or application) in which case it is sent to that, as that's the one object that still has the opportunity to take priority over the object specified by the importer's "dispatch directly to library" table.

Bypassing AS's established dispatch rules when dispatching commands that use `use`-imported terminology is NOT my complaint. My complaint is that it's buggering up how those commands' parameters are evaluated. It actually makes those parameters appear as if they're being evaluated within the *library* script instead of within the script in which they're actually declared. (Hence my initial flawed hypothesis.)

Your argument seems to be that if users' understanding of AS is sufficiently broken on all levels then somehow all that wrongness eventually comes together to produce a right explanation. Which is utter bull. If you say 1+2=2 and 2-1=2 and 2+2=4, therefore 1+2+2-1=4, the fact that you're final answer is right doesn't obviate the fact that your entire working is utterly wrong; it just means you got "lucky". Only you aren't really lucky at all, because now you're functionally wrong about everything and don't even realize it.

Let's face it, if you think you're understanding of AppleScript is correct, you're wrong. And you're probably the world's second-most expert on how the language works. And I say that with total confidence because I understand AppleScript better than you, and the damn thing still manages to spoof and misdirect me, as demonstrated on many an occasion. But the fact is, my explanation of what AS is doing here is effectively correct (subject to Chris P providing a more correct explanation, because unlike me he can spelunk the source to be 100% sure):

Keyword-based commands INVISIBLY REDEFINE the default target prior to evaluating their parameters; thus any commands appearing within those parameters [and which aren't explicitly targeted themselves] will be sent to the WRONG DEFAULT TARGET by the script's own definition.

If I write in an AS script:

    DO THIS (DO THAT)

and it does:

    DO THIS (DO THE OTHER)

that is not a feature, or even a "quirk", it is a giant honking incompetent cockup. It is not a documented behavior. It is not an expected behavior. The fact that you seem to think it's in any way expected, acceptable and/or forgivable just proves you ain't half as hot as a programmer as you think you are. But that's not my problem, it's yours.

This is something Chris P should've noticed when he was ingeniously hacking up 20 years of established message dispatch rules, and addressed there and then. He didn't, because nobody on the AS team ever bothers to dogfood their own damn code[1].



> > And you wonder why veteran AS devs like me and Mark
>
> Please skip the argumentum ad verecundiam...

Except, hey, guess what, me and Mark ARE what passes for AppleScript LANGUAGE experts around these parts. There's plenty bonafide experts as far as automating individual apps goes, simply by dint of personal accumulated experience of beating on them till they work - you for InDesign scripting, Paul for Office scripting, and so on. But the number of people in the world who possess even a remotely accurate understanding of how the language, its parser, and its interpreter work can be counted on the fingers of one hand; and since Cook and Harris are 20+ years out of it, I'm guessing they've long since blotted it out. Which leaves me and Mark; cos neither of the Chrises, despite having access to internal documentation and code, understand it remotely as well - as all their own work repeatedly proves. It's an utterly disgraceful state of affairs: certainly not a solid durable foundation for a technology on which Apple will happily let users and businesses be critically dependent. If Apple ran Swift like the run AppleScript, it would've dead before it got out the door, shunned by developers who weren't born yesterday and can spot a total catastrophe ready to bite everyone before ever hanging their own shingles on it as well.


> > Can't speak for Mark
>
> Exactly.


Except I *know* Mark got the willies too about Chris P butchering the AS parser for 10.9 cos he's said so. (Although his phrasing was more the "we live in interesting times" sort, cos he's impeccably polite and diplomatic at all times, even though the AS team totally ignores him too.)


has


[1] BTW, they're not the only Apple team who write crap code; so this is not specifically picking on them. The other Apple dev teams just happen to be serving a professional programmer audience where there's hundreds of users at least as educated as experienced as them to call them on their cockups. The AS team gets away with it because virtually nobody who uses AppleScript understands it anywhere completely or accurately enough to understand what's going on or why, never mind formulate meaningful criticism. Which I could still forgive were it not for the fact that when someone does realize what's going wrong and point it out, they point-blank ignore it. That's not Computer Science, it's Computer Religion. And I absolutely DESPISE it – why you think I taught myself AS in the first place?
_______________________________________________
Do not post admin requests to the list. They will be ignored.
AppleScript-Users mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
Archives: http://lists.apple.com/archives/applescript-users

This email sent to email@hidden


  • Follow-Ups:
    • Re: [FYI] more sdef-based library stupidity
      • From: Dave <email@hidden>
    • Re: [FYI] more sdef-based library stupidity
      • From: Shane Stanley <email@hidden>
  • Prev by Date: Re: ASObjC: Get Most Recent File or Folder
  • Next by Date: Re: [FYI] more sdef-based library stupidity
  • Previous by thread: Re: [FYI] more sdef-based library stupidity
  • Next by thread: Re: [FYI] more sdef-based library stupidity
  • Index(es):
    • Date
    • Thread