Disclaimer

The content of this blog is my personal opinion only. Although I am an employee - currently of Nvidia, in the past of other companies such as Iagination Technologies, MIPS, Intellectual Ventures, Intel, AMD, Motorola, and Gould - I reveal this only so that the reader may account for any possible bias I may have towards my employer's products. The statements I make here in no way represent my employer's position, nor am I authorized to speak on behalf of my employer. In fact, this posting may not even represent my personal opinion, since occasionally I play devil's advocate.

See http://docs.google.com/View?id=dcxddbtr_23cg5thdfj for photo credits.

Sunday, June 12, 2016

I must learn to live with broken software

I must learn to live with broken software.



When software tools that I have to use are broken, I must work around the brokenness as quickly as possible.



I must resist the temptation to try to figure out what the brokenness is. Unless doing that is quick.   I must not waste hours banging my head against stupid tools like Perforce.



This is especially important for commercial software.   With Open Source software, at least there;'s a chance that I can fix the brokenness - but with proprietary software, that is unlikely.



Although I believe that it is important to report bugs so that they can be fixed,



When something is broken, I need to find the quickest path around the brokenness.



---



The worst brokennesses for me are the ones that are only a little bit broken.  That mostly work, except for some stupid thing, that one might hope can be fixed with little duct tape and shell script wrapper.



---



I went looking for inspiring quotes about this topic - advice on how to decide quickly whether it is worth trying to work through versus work around software brokenness.



This is the closest I have come, from the original wiki: http://c2.com/cgi/wiki?DoesSoftwareMakeUsersHappy:  Does Software Make Users Happy: "Techies have accommodated to broken software"



Not so great in context, since the poster is making an argument for SW perfectionism.



---



That may be the pithy phrase that I am looking for:



How to know when it is better to work around versus working through software problems.



Especially for software that you are using, not producing.



Probably also beyond software.


Mac OS X 'LSOpenURLsWithRole() failed with error -10810 for the file ...'

BRIEF:



LSOpenURLsWithRole() failed with error -10810 for the file ...


can be caused by trying to open a script
that itself calls /usr/bin/open

I.e. MacOS /use/bin/open is not trivially reentrant.

DETAIL


Alvin Alexander provided some clues to this MacOS error:

Mac OS X 'LSOpenURLsWithRole() failed with error' | alvinalexander.com



I had a slightly different cause of

LSOpenURLsWithRole() failed with error -10810 for the file ...



I have some shell scripts that call "open SOME-MAC-APP",

where open = /usr/bin/open

$ bash 1349 $>  open -h
Usage: open [-e] [-t] [-f] [-W] [-R] [-n] [-g] [-h] [-b <bundle identifier>] [-a <application>] [filenames] [--args arguments]
Help: Open opens files from a shell.
      By default, opens each file using the default application for that file.
      If the file is in the form of a URL, the file will be opened as a URL.
Options:
      -a                Opens with the specified application.
      -b                Opens with the specified application bundle identifier.
      -e                Opens with TextEdit.
      -t                Opens with default text editor.
      -f                Reads input from standard input and opens with TextEdit.
      -F  --fresh       Launches the app fresh, that is, without restoring windows. Saved persistent state is lost, excluding Untitled documents.
      -R, --reveal      Selects in the Finder instead of opening.
      -W, --wait-apps   Blocks until the used applications are closed (even if they were already running).
          --args        All remaining arguments are passed in argv to the application's main() function instead of opened.
      -n, --new         Open a new instance of the application even if one is already running.
      -j, --hide        Launches the app hidden.
      -g, --background  Does not bring the application to the foreground.
      -h, --header      Searches header file locations for headers matching the given filenames, and opens them.



such as "open /Applications/p4v.app".





Trying to make a shell script that calls open

into an app that can itself be called via open seems to be not supported

- i.e. open is not reentrant, and least not trivially.



It is this "open within an open" that was causing

LSOpenURLsWithRole() failed with error -10810 for the file ...


I have two scripts, p4v (which calls "open /Applications/p4v.app), and p4v-ag (which executes the executable with that app)

$ bash 1258 $>  diff p4v p4v-ag
16c16
< P4_EXECUTABLE=/Applications/p4v.app
---
> P4_EXECUTABLE=/Applications/p4v.app/Contents/MacOS/p4v
18c18
< open "$P4_EXECUTABLE" $@
---
> "$P4_EXECUTABLE" $@




 The p4v-ag script (the other can be inferred)

$ bash 1259 $>  cat p4v-ag
#!/bin/sh
# Simple script to run Perforce (P4) commands on macos
export P4CONFIG=.p4config
P4_EXECUTABLE=/Applications/p4v.app/Contents/MacOS/p4v
"$P4_EXECUTABLE" $@
I make both of these shell scripts into MacOS apps

$ bash 1261 $>  macos-appify p4v
/Users/glew/bin/p4v.app
$ bash 1262 $>  macos-appify p4v-ag
/Users/glew/bin/p4v-ag.app
Running the open with open gives the error:



$ bash 1263 $>  open ./p4v.app
LSOpenURLsWithRole() failed with error -10810 for the file /Users/glew/bin/p4v.app.
✗ 
Running the other does not.

$ bash 1264 $>  open ./p4v-ag.app
✓ 

Tuesday, June 07, 2016

Macro - Simple code templating mechanism - for Perl

Macro - search.cpan.org: "Macro - Simple code templating mechanism"



Too bad ... doesn't seem to work.   Perl v5.18.2



I was driven to try this because I am tired of typing  Data::Dumper's repetition.





'via Blog this'

Thursday, June 02, 2016

Should asserts be disabled in production?

I used to be quite annoyed by Perl CPAN's

Carp::Assert: "assert(...) if DEBUG;"
i.e. by the fact that you have to append "if DEBUG" to an assertion in order to get it disabled in production.



Now, I have flipped.



I often want assertions enabled in production code. At least cheap assertions.  In fact, I might go so far as to say "assertions should be enabled in production code by default, unless you explicitly say not to".



In which case, the Perl Carp::Assert syntax is not totally unreasonable.



I might prefer the Pythonish



if DEBUG: assert(...)



so that you can see the "if DEBUG" right up front.



But then again, Python's assert is disabled when you run Python "optimized" via python -O.



I was somewhat flabbergasted when I encountered Python style guides that recommended not using asserts, or specifically not using asserts inside library functions.    (Can't find a reference right now, so perhaps this is rare advice.)



Reason: since Python assert is disabled when you run optimized -O (which is common in some worlds), and since libraries cannot be sure that somebody competent is calling them, libraries should do

if !valid(parameter): raise someException
rather than

assert valid(parameter)
This advice is accurate, but unfortunate.  I always prefer concise code, and "assert" is more concise than "if...raise".   And probably less fragile, since exception hierarchies have a habit of changing.





So I can't blame Python, but I can still regret it.






Principle of Smallest Scope

My mini-flame about a comment that might be interpreted as idiotically forbidding declaring a named subroutine inside a named subroutine inspired me to write this blurb about "The Principle of Smallest Scope".



I don't think I originated this principle, although I have practiced it for (ahem) decades, in (ahem) two different centuries. (ahem, probably scared off lots of headhunters: too old)



However, googling could not find me a reference for 'Principle of Smallest Scope'. Perhaps after I write this it will.  (Perhaps also I just misremembered the name - "Principle of Least Scope"? "Principle of Most Restricted Scope"?  If so, I will update this blog with a pointer to a better name.)



The Principle of Smallest Scope is much like the Law of Demeter, although that is more about object oriented design, whereas POSS applies to non-object systems.  Both are just particular forms of information hiding.



So, what do I mean by the 'Principle of Smallest Scope'?



I mean that definitions, both named and anonymous, should be restricted to the smallest reasonable scope.



E.g. it is bad to use a global variable when a procedure local variable is sufficient.



E.g. within a procedure, you may have temporary variables - e.g. small local common subexpression elimination.

...
ret := big_complex_function_returning_struct(...)
print ret.to_string()
assert( not ret.is_error() )
next_function( ret.field1, "do more stuff" )
...
if idioms like this are used over and over, then I think you should restrict the scope of ret, if your language permits it:

sub some_function () {
    ...
    {
        ret := big_complex_function_returning_struct(...)
        print ret.to_string()
        assert( not ret.is_error() )
        next_function( ret.field1, "do more stuff" )
    }
    ...
    {
        ret := another_big_complex_function_returning_struct(...)
        print ret.to_string()
        assert( not ret.is_error() )
        another_next_function( ret.fieldA, "different but similar" )
    }
    ...
}

rather than
sub some_function () {
    ...
    ret0 := big_complex_function_returning_struct(...)
    print ret0.to_string()
    assert( not ret0.is_error() )
    next_function( ret0.field1, "do more stuff" )
    ...
    ret1 := another_big_complex_function_returning_struct(...)
    print ret0.to_string()
    assert( not ret1.is_error() )
    another_next_function( ret0.fieldA, "different but similar" )
    ...
}
E.g. it is good for a programming language to support scopes that are smaller than function scope.

    Python fails this.



E.g. it is good to be allowed to declare named subroutines within named subroutines - and for it to be illegal to access the inner named subroutine outside of its enclosing scope.  (At least, illegal by default.)

    Perl fails this.



E.g. ditto nested classes.  Lexically nested whatevers.









Now, I admit: masking of names can be confusing.  It may be good to warn.   It may also be good to require explicit override.





More later...















 









Variable will not stay shared in subroutine

Variable will not stay shared in subroutine: "The correct solution is not to declare a named subroutine inside a named subroutine."
'via Blog this'
This sort of comment pisses me off.   Nesting and lexical scope are some of the most valuable concepts in programming language design.



Just as security has the Principle of Least Privilege, programs should usually take advantage of the Principle of Smallest Scope.



Temporary values should have the smallest scope possible.



Helper functions are just temporary values that happen to be code.  It should be possible to define lexically nested functions that are not visible outside the lexical scope.



Perhaps the author of the comment that pissed me off may have meant to be more specific: "Perl's implementation of 'nested subroutines' is misleading, and should not be used because of this possible confusion."



Not least because Perl's 'nested subroutines' are not really lexically nested.  Instead, they are (as poster Ovid earlier in the thread before the4 comment that pissed me off says):

[Named] subroutines are entries in the current namespace's symbol table (in a typeglob slot) and this does not allow for nesting. As the docs explain, this can be gotten around by using an anonymous subroutine because these get stuffed in a scratchpad, thus making them lexically scoped.
Also, it is quite confusing that 'nested name subroutines' and 'nested anonymous subroutines' have such different behavior.



It is also fair to say that this specificity may have been implied by context.  I should not get pissed off so easily.



But on the technical issue, yeah, Perl's funky support for not-really-lexically-nested-named-functions is a piss-off.



---



I think I am annoyed by this because recently I have writing Python to use pyobjc on my Apple MacBook  - and Python does not have lexical scopes apart from functions and modules.  So Python does not support the Principle of Smallest Scope.  At least up to Python3.  Perl mostly supports the Principle of Smallest Scope - except for stupidities like this not-really-lexically-nested-named-functions.