Re: Next Apocalypse
On Sat, 13 Sep 2003, Luke Palmer wrote: > Also, the "standard library", however large or small that will be, will > definitely be mutable at runtime. There'll be none of that Java "you > can't subclass String, because we think you shouldn't" crap. Java's standard class library is a mishmash of things that represent containers (variables) and things that represent values (and even some broken things that try to be both), with no syntactic help to distinguish them. And its syntax reserves "const" but doesn't use it for anything. As long as we have "is rw" and its friends, we can -- with suitable care -- make sure that a subclass of a value-representing class is also a value-representing class, so there's no semantic need to say "never any subclasses" but we can still do CSE and other neat stuff at compile time. Of course having a "no subclasses" tag means the compiler can change a method call into a direct subroutine call, but I would hope that method calling will be fast enough that it won't need to. Will we require methods in subclasses to use the same signatures as the methods they're overriding? -Martin -- 4GL ... it's code Jim, but not as we know it.
Re: Next Apocalypse
On Mon, 15 Sep 2003, Dan Sugalski wrote: > > Great. But will it also be possible to add methods (or modify them) > > to an existing class at runtime? > > Unless the class has been explicitly closed, yes. That strikes me as back-to-front. The easy-to-optimise case should be the easy-to-type case; otherwise a lot of optimisation that should be possible isn't because the programmers are too inexperienced/lazy/confused to put the "closed" tags in. And it would be a better chance to warn at compile time about doing things which are potentially troublesome. But whichever way this goes, I take it we'll have warnings like: Changed method definition Class::foo may not take effect in pending initialiser at program.pl line 9. Overridden method definition MyClass::foo (new subclass of Class) may not take effect in pending function bar() in zot() at Zot.pm line 5 in other() at Other.pm line 10 at program.pl line 123.
Spare brackets :-)
This may sound like a silly idea but ... Has anyone considered removing with the syntactic distinction between numeric and string indexing -- that is, between array and hash lookup? In particular, it would seem that %foo[$key] would be just as easy for the compiler to grok as %foo{$key} but would mean that we could stop worrying about the precedence of postfix/infix "{", and things like if %test { $count++ } would not require whitespace before the "{" to be disambiguated. I don't have a complete solution as anonymous array and hash construction would still need different syntaces, but has anyone else thought about this? - Martin
Re: L2R/R2L syntax
On Sat, 25 Jan 2003, Damian Conway wrote: > As far as I know Larry is not planning to remove the functional > forms of C, C, etc. > > Those forms may, it's true, become mere wrappers for the OO forms. > But I confidently expect they will still be available. Hmmm, so that means that they should be overloadable on a per-arrayish-class basis, no? Then what happens to @A = map { ! $_ } @B, @C; when @B and @C are different classes? Does that transmogrify into @A = ( @B.map { ! $_ }, @C.map { ! $_ } ) or into @A = [ @B, @C ] .map { ! $_ } ? -Martin
Re: Spare brackets :-)
>> In particular, it would seem that >> %foo[$key] >> would be just as easy for the compiler to grok as >> %foo{$key} On Mon, 27 Jan 2003 15:39:19 -0800, Damian Conway <[EMAIL PROTECTED]> wrote: > Sure. But then is this: > > $ref[$key] > > an array or hash look-up??? Yes, well I suppose that could be considered one of the things I hadn't figured out yet. But is seems to me that if we're changing "$X[$n]" to "@X[$n]", then it would be more consistent to change "$ref->[$key]" to "@$ref[$key]". Except of course that mixing prefix and postfix notation is horrible, so perhaps "$ref@[$key]" and "$ref%[$key]". (I'd assumed that "%[" and "@[" would be single symbols?) > Decided at runtime? That might be OK, except (as others have pointed out) for auto-vivification, where the object doesn't exist before we operate on it. Maybe we would get away with the shorthand "$ref[$index]" *except* where autovivification is desired, and then we'd have to use the long-hand "$ref@[$index]" and "$ref%[$index]" versions? Hm, actually, I think I could class that as a feature, if the reader -- human or compiler -- could know just by looking whether auto-viv is expected. -Martin
Re: infectious traits and pure functions
I wrote: > > In the general case, if your language has both pure and impure > > functions, proving (at compile time) that something is not impure is an > > NP-complete problem. On Mon, 16 Feb 2009, Mark Biggar wrote: > Worse it's equivalent to the halting problem (I.e., not solvable). Quite correct, my mistake. Please read as s/NP-complete/halting problem/g -Martin
Re: Temporal and purity (was: Re: IO, Trees, and Time/Date)
On Fri, 20 Feb 2009, Timothy S. Nelson wrote: > On Thu, 19 Feb 2009, Martin D Kealey wrote: > > Rather, let's have immutable time "values", and methods which return other > > "values" where various computations (*1) have been applied. Provide > > constructors which take the Y/M/D/h/m/s/dst_now/dst_rule tuple. > > I followed the bits about the computations, and I think I see what > you're saying about the constructor, but I don't know what you mean by > 'immutable time "values"'. Could you expand on this a bit? We want an "Instant" class whose objects have value semantics rather than container semantics. Because: 1. It makes them usable in "pure" code 2. "Date isa Instant" works sensibly: anywhere that expects an Instant, you can give it a Date. (Assuming we all agree that dates start at midnight, but then we *are* talking specifically Gregorian dates.) (If you have container objects, that can't work, and neither can the reverse, tempting though it is. So tempting in fact that it's part of the Java language definition. Uggh!) 3. Having separate writable attributes is offering someone a cannon with which to shoot their own foot off, as far as having buggy code goes. (Strictly, this doesn't preclude having a container object where you set the epoch-second, or set the year, month, day, hour, minute and second all at once, but even if they're not in the design to begin with, sometime someone naïve is going to add them. 4. Let's face it, they're pretty small objects. They're on a par with a "Num", and should get similar treatment. -Martin
Re: Junction Algebra
On Mon, 30 Mar 2009, Mark J. Reed wrote: > > ( $a <= any(-1,+1) <= $b ) == ( $a <= any(-1,+1) && any(-1,+1) <= $b > > ) > > Clearly, the RHS is true for $a == $b == 0, but I'm not sure the LHS > shouldn't also be. Isn't it just syntactic sugar for the RHS? I suspect not. Rather I think that $a <= any(-1,+1) <= $b corresponds to $tmp = any(-1,+1); $a <= $tmp <= $b and thence to $tmp = any(-1,+1); $a <= $tmp && $tmp <= $b The more I think about this, the more I come to the conclusion that a junction should appear to have a uniform (single) value in each "eigenthread". > Logically, you might want it to mean something like ∃$x: $x == any(-1,+1) > && $a <= $x && $x <= $b, but I don't think it does. I think that flows fairly cleanly from the Junction-isa-Object implementation, and the way that references are taken. This is not going to play well with subexpression folding: junctions have to be considered "unclean", in that two junctions must not be merged even if they're immutable and indistinguishable (except for object identity). $a = any($x, $y); $b = any($x, $y); assert $a !== $b; Earlier Moritz suggested that one could modify an external object from within the eigenthreads to accumulate the list of eigenstates, in defiance of having the !eigenstates() method private. That's almost reasonable, but it assumes that eigenthreads don't work on separate snapshot copies of the world, and that those snapshots aren't discarded after their results are flattened by the junctive operator. -Martin
Re: junctions and conditionals
On Tue, 31 Mar 2009, Jon Lang wrote: > Another issue: what happens if conditional code mutates a junction > that it filtered? For example: > > $x = any (-5 .. 5); > if $x > 0 { $x++ }; > > At this point, which of the following does $x equal? > > any(-4 .. 6) # the original junction gets mutated > any(-5 .. 0, 2 .. 6) # the filtered part of the original junction > gets mutated; the rest is untouched > any(2 .. 6) # the filtered part of the original junction gets > mutated; the rest is lost I choose #3. Reality can only take one path through a conditional; which one depends on the one/any/all/none binding of the junction. Once you've passed the conditional, you have: one -> single matching value (no longer a junction) any -> filtered list all -> original junction none -> empty (*1) The "threading" is an implementation detail; the important thing is a junction is collection of values and a smart way of rewriting expressions that contain them, with special treatment for comparison operators (or indeed anything that forces Boolean content): $x CMP all($y,$z) $x CMP $y && $x CMP $z $x CMP one($y,$z) $x CMP $y ^^ $x CMP $z (*2) $x CMP none($y,$z) all($x !CMP $y, $x !CMP $z) $x CMP any($y,$z) $x !CMP none($y, $x) $x OP all($y,$z)all( $x OP $y, $x OP $z) $x OP any($y,$z)any( $x OP $y, $x OP $z) $x OP one($y,$z)one( $x OP $y, $x OP $z) $x OP none($y,$z) none($x OP $y, $x OP $z) -Martin (*1: An argument could be made that "none" should leave the junction alone, the same as "all".) (*2: I would like to suggest that the semantics of "one" be changed to mean "pick one" (randomly) rather than "exactly one". In this respect it would be the same as "any" except it wouldn't have the overhead of filtering *every* match, just at least one.)
Announcing Rakudo Perl 6 Development release #26 ("Amsterdam")
On behalf of the Rakudo development team, I'm pleased to announce the February 2010 development release of Rakudo Perl #26 "Amsterdam". Rakudo is an implementation of Perl 6 on the Parrot Virtual Machine (see http://www.parrot.org). The tarball for the February 2010 release is available from http://github.com/rakudo/rakudo/downloads . Rakudo Perl follows a monthly release cycle, with each release named after a Perl Mongers group. The February 2010 release is code named "Amsterdam" for the largest chapter of the Dutch Perl Mongers. Perl development enjoys considerable support from the Netherlands, with donations from NLNet, and hosting of the feather machines and several important Perl 6 web domains and sites. This release is the first release based on the new branch of Rakudo development begun in October 2009. The branch refactors the grammar, object metamodel, and a number of other key features to improve compatibility with the Perl 6 specification and give us a more solid foundation to build on. Indeed, in many ways the development of this new branch has driven important changes to the specification in the areas of lists, iterators, slices, and much more. However, this release contains a number of significant regressions from previous compiler releases. We expect to have full functionality restored in this branch in the next couple of weeks. For those looking to explore a wide variety of Perl 6 features or who have applications developed using previous releases of Rakudo, you may wish to continue to use the January 2010 (#25, "Minneapolis") release. This release of Rakudo requires Parrot 2.1.0. One must still perform "make install" in the Rakudo directory before the "perl6" executable will run anywhere other than the Rakudo build directory. For the latest information on building and using Rakudo Perl, see the README file section titled "Building and invoking Rakudo". Some of the specific changes and improvements occuring with this release include: * Now using nqp-rx for parsing and actions * Grammar is much closer to STD in many aspects, and makes use of protoregexes * Closures and lexical/contextual variable declarations in regexes work * Laziness is implemented * All class and role construction is handled through the meta-model The Perl 6 language specification is still in flux. Please take note of the following changes, which might affect your existing programs. In the next release of Rakudo, the deprecated features will likely be gone. * The root of the object hierarchy has been changed from 'Object' to 'Mu'. The type 'Object' goes away. * The term 'undef' is gone. You can replace it with other constructs, depending on context: - 'Nil' is undefined in item context, and the empty list in list context - 'Mu' is the most general undefined value which does not flatten in list context - as a smart matching target, you can replace '$obj ~~ undef' by '$obj ~~ *.notdef' * Builtin classes will derive from 'Cool' (which itself derives from 'Any'). Most of the builtin methods on these classes will be defined in the 'Cool' class instead of 'Any'. See Synopsis 2 for more details. * Starting with the this release, release identifiers are given as ".MM" instead of "-MM" (dot instead of hyphen). This is intended to simplify building and packaging for other distribution systems. The development team thanks all of our contributors and sponsors for making Rakudo Perl possible. If you would like to contribute, see http://rakudo.org/how-to-help , ask on the perl6-compi...@perl.org mailing list, or ask on IRC #perl6 on freenode. The next release of Rakudo (#27) is scheduled for March 18, 2010. A list of the other planned release dates and codenames for 2010 is available in the "docs/release_guide.pod" file. In general, Rakudo development releases are scheduled to occur two days after each Parrot monthly release. Parrot releases the third Tuesday of each month. Have fun! [1] http://www.frozen-perl.org/ [2] http://use.perl.org/~pmichaud/journal/39779 [3] http://use.perl.org/~pmichaud/journal/39874
Re: ./method
On 5/15/05, Juerd <[EMAIL PROTECTED]> wrote: > A few days ago, when typing ./pugs,... You can guess the rest :) > > I suggest > > ./method > > to mean $?SELF.method, and > > ../method > > to mean $?SELF.SUPER::method, or however that's normally written. > > This syntax doesn't clash with anything, doesn't introduce whitespace > asymmetry and doesn't require anything other than ASCII. > > If you go back to what inspired it, the mnemonic becomes clear: unix > filesystems. However, it's far fetched and none of the people I've asked > think it's a good one. Still, it works for me and may even work in > textbooks. > > The best thing about this new proposal is that everyone so far agrees > that it's feasible, easy to write and not ugly. I have tried, but I can't make myself like it. The syntax surely is feasible, easy to write and not ugly, but it makes me think about objects in terms of pathnames with . meaning $?SELF and / where "other languages" use the dot, except I can't use it for anything but a method call on the implicit receiver. It also makes me want to propose zsh-extended-glob-compatibility syntax for objects so I can have method/attribute slices, and then I end up curled up in a corner, scared and shaking. But maybe I should just get used to that. :-) > Juerd Martin
Re: [perl6/specs] 5277fe: Add expmod and is-prime as built-ins in Int
On Thu, 20 Sep 2012, Stephen Pollei wrote: > If it says it might be prime it's > about a 50% 50% split if it's correct. According to Wolfram, it's 75/25; so a positive result after 10 iterations leaves about a one-in-a-million chance of being composite (more precisely, one in 1048576). > multi method is-prime ( Int $x: Int $tries = 100) is export > should also at least document that tries is never a negative number, > or if it is that it has same behaviour as zero. Logically if "tries" is zero, is-prime shouldn't do any testing at all, and should always return "true". (There's a chance it might be prime!) If "tries" is negative, which idiom should we follow: * a range iterator (empty, zero tries, return true) * arrays etc count-backwards-from-the-end (keep trying until certain) * a logical ambiguity (return Any(true,false)) * you-get-what-you-ask-for (return "PEBKAC":but(false) ) * a logical contradiction (return an unthrown exception) * a formal error (throw an exception) -Martin
Re: Recommended Perl 6 best practices?
On Tue, 30 Sep 2008, Patrick R. Michaud wrote: > Just for pedantic clarity, what C< $directive ne 'VAR' & 'LOOP' & 'IF' > > really gives is > > all( $directive ne 'VAR', $directive ne 'LOOP', $directive ne 'IF' ) > > In other words, the result of the expression is an all() Junction. In > boolean context this would indeed evaluate to false if $directive has any > of the values 'VAR', 'LOOP', or 'IF'. Does it have to be this way? In formal logic, distributing a negation over a disjunction products a conjunction and vice versa. Perl has a long tradition of dwimmery, so why are we taking a literal "distribute all symbols the same way" approach? Surely it is more important that ($a ne $b) should be equivalent to not( $a eq $b ) regardless of whether either variable contains a junction? As a start, perhaps we should be marking certain operators (not ! none() != ne) with whether they represent a logical inversion, so that conjunctions and disjunctions can be alternated? -Martin Kealey
Re: S16: chown, chmod
On Tue, 25 Nov 2008, Dave Whipp wrote: > Brandon S. Allbery KF8NH wrote: > > Still misunderstanding, I think. Yes, it will fail anyway, but in the > > general case you're checking to see if as a privileged process it is safe to > > operate on a given file. > > I'd actually been thinking that one would use the check in the opposite > direction: > > if need_priv() { > sudo { ... }; # might ask user for passwd > } > else { > ... > } > > But then I'm not an expert in this area: I just want an API that makes it easy > to hack simple scripts that do what I need. It was C that I really > wanted to improve the API for; I touched C only because it was adjacent > in the POD, and it seems reasonable for the two functions/methods to have > similar look&feel. I've been wondering about this idiom, used when copying files: my $s = POSIX::stat($filename1); POSIX_extensions::setstat($filename2, $s); where setstat() is a combination of chown, chmod and utime -- in the right order to make them work as best as possible. The type of check contemplated in this thread would then come in handy for implementing setstat(). If an unprivileged user can give away a file then that change has to be the last thing done to the file. Otherwise changing the permissions should be done last, so as to maintain the set*id bits. So I would envisage it would look a bit like this (please excuse my obvious hand-waving pseudocode): sub setstat(String|File $filename, StatBuf $stat) { use fatal :everything; if $stat.uid != any(POSIX::getuid(), POSIX::geteuid()) | $stat.gid != any(POSIX::getgid(), POSIX::getegid(), POSIX::getgroups()) { # we need to give the file away my $caps = POSIX_1e::capget(); if $caps.CAP_FOWNER { # we're privileged, so it *should* just work. POSIX::chown $filename, $stat.uid, $stat.gid; POSIX::chmod $filename, Fcntl::ST_PERM($stat.mode); POSIX::utime $filename, $stat.mtime, $stat.atime; return; } if $caps.CAP_CHOWN | !chown.need_priv() { # we have enough privilege to give the file away, but not enough to # touch it after we've done so. POSIX::chmod $filename, Fcntl::ST_PERM($stat.mode); POSIX::utime $filename, $stat.mtime, $stat.atime; POSIX::chown $filename, $stat.uid, $stat.gid; return; } if catching_exception(IO_error) { throw IO_error(EPERM, $filename, "Can't give file away"); } } # can't (or don't need to) give file away POSIX::chmod $filename, Fcntl::ST_PERM($stat.mode); POSIX::utime $filename, $stat.mtime, $stat.atime; } -Martin
Re: RFD: Built-in testing
On Wed, 21 Jan 2009, Damian Conway wrote: > > Maybe something in all caps. For what it's worth, :OK<> can be typed > > with one hand while the other holds down the shift key. :) > > Typical right-hander fascism! On the other hands we have :QA ... which also so happens to be an apposite abbreviation. :-) -Martin
Re: infectious traits and pure functions
On Fri, 13 Feb 2009, Jon Lang wrote: > In reading about functional programming, I ran across the concept of > the "pure function" - i.e., a function that doesn't produce side > effects. [...] > It occurred to me that this business of marking functions as pure could be > done in perl by means of traits Excellent plan. But it's actually impurity that is infectious -- an impure function being any function that might modify an object whose lifetime exceeds the invocation of the function, either directly or by calling another impure function. In the simple case that devolves to "you're impure if you call another impure function, or modify anything in an outer scope". But if you have objects and nested functions, the exact inference rule gets a whole lot more complicated. With exceptions, threads and co-routines it's a nightmare. In the general case, if your language has both pure and impure functions, proving (at compile time) that something is not impure is an NP-complete problem. So you really want the programmer to mark them for you, and to have run-time checking to make sure assumptions are not violated. And to encourage efficiency generally, you want the Huffman coding for "pure" to be shorter than the Huffman coding for "impure", or better still, "pure by default". Perhaps anonymous code using the arrow notation should be implicitly ":pure"? Another approach would be to treat purity like class finalization: start by assuming you have pure functions, but go back and regenerate them if you discover that a sub-function somewhere is actually impure. It won't be trivial, given that you'll have to restart the regenerated code somewhere in the middle. Something else to be considered: we're close to reaching the limit on CPU clock speed -- maybe only one more order of magnitude over the next couple of decades. From here on the big gains will be from packing ever more cores into a CPU, and development massively parallel software to take advantage of them. Applicative languages have a huge head-start on that; their no-overwrite rule ("there are no variables, only values") means that data-flow dependencies are *always* obvious, so very fine-grained parallel scheduling can be used get a performance gain from every extra hyperthread (*1). Although Perl6 will get quite a boost from various code migration techniques, probably the biggest win will be from such implicit massive micro-threading. If Perl6 can dispatch lots of threads all the time, not just with "map" or "grep", then it will make the best possible use of the available hardware. However for this to be possible, just being "pure" won't be enough. It will also need: (A) cacheable functions whose return value depend only on the declared parameters (this is orthogonal to not modifying the external environment); and (B) truly immutable objects, and declarative ways to guarantee them in all contexts, such as: * immutable function parameters (that can't be changed by the function) * constant function parameters (that can't be changed by someone else while the function is looking at them, even by other threads or coroutines) * deep auto-cloning mutable "container" objects into immutable "value" ones * auto-boxing immutable "value" objects into "container" objects -Martin (*1: Google for the report by G Y Matthews (Sydney University, 1994) on reformulating the "Magma" mathematical research language as an applicative language.)
Re: infectious traits and pure functions
On Mon, 16 Feb 2009, Jon Lang wrote: > if there's any doubt about the matter (e.g., conclusively proving or > disproving purity would be NP-complete or a halting problem), then Deciding whether you have a halting problem IS a halting problem... :-) -Martin
Re: Detecting side-effects in Perl 6 (Was: Re: infectious traits and pure functions)
On Tue, 17 Feb 2009, TSa wrote: > I fully agree that immutability is not a property of types in a signature. > But a signature should have a purity lock :(Int $i is pure) that snapshots > an object state [...] > Note that this purity lock doesn't lock the outer object. It is only > affecting the inner scope controlled by the signature. So there have to be > extra means of snapshot generation if a mutable object shall be given e.g. > to multiple invocations with the same snapshot state. This is no problem > for code downstream of a purity lock because snapshotting a pure object is > a no-op. I like the way this is going; ".snapshot" works like ".deepclone" when you have an ordinary object, but like ".self" on one that already has a purity lock, OR any time you can prove that the object is actually at its end of life (*1). An important class of optimizations in the implementation of pure functional languages is the destructive re-use of object that have reached their end of life according to the data-flow analysis; they can be reused to hold some subsequent value, most typically by doing an in-place update. So you need an operation that changes a snapshot back into live object. It's also going to be important that "snapshot" do as little work as possible even when objects get handed around by impure code; to this end it would be really useful to be able to pass snapshots to impure code and guarantee that they won't get mangled, so they can later be passed to more pure code (*2). Question: does/should MMD differentiate between :ro and :rw parameters or invocants that are otherwise identical? -Martin *1: actually it's a bit more complicated; a mutable object can be re-tagged as immutable iff it's at end-of-life according to data-flow analysis AND all its contained sub-objects are either already immutable or can in turn be re-tagged as immutable. Otherwise it has to make a shallow clone, and the process repeated recursively for all contained mutable objects. *2: There are at least three ways of doing this: 1. When re-tagging an immutable object as mutable, make a deep clone. 2. When re-tagging an immutable object as mutable, make a shallow clone. Any time subsequently an immutable sub-object is about to be used an a potentially mutating way, re-tag or clone it too. 3. Wrap the object in a new proxy (*3) object, that defers the cloning until its actually needed. The big win on this is that if you subsequently "snapshot" the proxy, it just gives you back the original object. Possibly methods 2 & 3 can be combined into a self-mutating proxy that becomes the clone when needed. *3: I call it a proxy because it defers all non-mutating method calls to the original object, and for the mutating ones, does the clone thing and then defers the method to the clone. Which might be itself.
Re: IO, Trees, and Time/Date
On Wed, 18 Feb 2009, Timothy S. Nelson wrote: > I'll try and design an API that does what DateTime does, but: > 1. Uses more variables, of which I expect the getters and setters to be > overridden. Please let's NOT have setters on "time" objects. They're a source of subtle bugs in such client code AND having mutable objects means you can't use them in otherwise pure code. (See the separate thread on immutability and purity.) Rather, let's have immutable time "values", and methods which return other "values" where various computations (*1) have been applied. Provide constructors which take the Y/M/D/h/m/s/dst_now/dst_rule tuple. And please let's not have any implied "default" timezone. That's not to say it has to be difficult or cumbersome, just explicit, perhaps something like one of these: my &localtime = DateTime::Gregorian.localize( :host_default ); my &localtime = DateTime::Gregorian.localize( :user_env ); my &localtime = DateTime::Gregorian.localize( :http_client(%http_client_headers) ); my &localtime = DateTime::Gregorian.localize( :db_server($odbc_handle) ); my &gmtime= DateTime::Gregorian.localize( :utc ); my &swatch= DateTime::Gregorian.localize( :tz('Europe/Geneva'), :no_dst ); -Martin *1: Operations on localtime objects involve differences, offsets and baselines, expressed in a range of units. The core units are seconds, minutes and days which are almost-but-not-quite exact multiples of each other (consider leap seconds (*2) and daylight saving). It is up to the client code to choose whether to treat an "hour" offset as exactly 1/24 day or as exactly 60 minutes. If you want a sunrise-based local time then that's a different library entirely. In the Gregorian and Julian calendars a "year" is an exact multiple of a "month", which is not an exact multiple of any core unit. A true astronomical calendar will take a "lunar month" to be ~2.551E6 seconds and a "solar year" to be ~3.1557E7 seconds; a tabular calendar will need them to be yet more separate offset types, and a separate library. *2: Or not, if you're on a POSIX host, in which case you sometimes get a peculiar "second" that takes twice as long as most, while a "minute" is always and precisely 60 "seconds".
Re: Temporal changes (was: Re: r25445 - docs/Perl6/Spec/S32-setting-library)
On Fri, 20 Feb 2009, Dave Rolsky wrote: > > > Renamed Temporal::Instant to Temporal::DateTime > > > > Hmm. We had some mailing list discussion about this, and agreed on > > Instant. I'd like to see your reasons in favour of DateTime. > > Because DateTime makes sense and is a clear description of what the thing > is. Instant is incredibly ambiguous, and not a common term for such > things. I think people are starting to argue at cross purposes here. An instant and a date-time are NOT the same thing. Barring limitations imposed by the speed of light and aberrations caused by relativity, and an instant occurs everyone at the same time. A date-time, if it's really true to its name, represents some 40-ish different instants, depending on which timezone it's interpreted in. At some point you have to decide which fictions are useful vs where you really need to hold out for reality. * First fiction: the speed of light is infinite, so instants really are universal. Unless you're writing GPS control software, you're probably OK with this. * Second fiction: the earth rotates at exactly 1/1440 rpm, so UT1=UT. POSIX's "epoch seconds" pretty much enforce belief in this, so if you don't want to believe it, you're going to have to build your own time libraries from scratch. * Third fiction: the day matches the rotation of the earth. In some places the law requires you both to believe and disbelieve this simultaneously. (For example, it may require that you're billed 10 minutes for a phone call that started at 01:55 and finished at 03:05.) * Fourth fiction: it's legally the same time everywhere on earth, especially for registration of births, deaths and marriages. (For example, if I move from my native New Zealand to, Hawaii, I will 23 hours older at my next legal birthday than I would be if I remained in NZ. Probably I'd be a day younger when I die too.) * Fifth fiction: everyone speaks English. It seems there is scope for multiple types, starting with Instants (which must believe fiction 1 and may or may not believe fiction 2), DateTime (which is agnostic about fiction 3), and "Localtime" and "Date" (which believe fictions 3 and 4). For each of these you have corresponding variants of Duration. So my question is, which of these fictions should the core temporal type(s) believe or disbelieve? Then we should name them appropriately. -Martin PS: IMHO core types should believe 1 & 2, and disbelieve 3 & 4, and avoid doing anything that depends on believing 5.
Re: Temporal changes (was: Re: r25445 - docs/Perl6/Spec/S32-setting-library)
On Mon, 23 Feb 2009, Timothy S. Nelson wrote: > > > > Renamed Temporal::Instant to Temporal::DateTime > > > > > > Hmm. We had some mailing list discussion about this, and agreed on > > > Instant. I'd like to see your reasons in favour of DateTime. > > > > Because DateTime makes sense and is a clear description of what the thing > > is. Instant is incredibly ambiguous, and not a common term for such things. > > Hmm. Ah, I can see why it's ambiguous. For those who missed it, think of > what "instant" means in the context of "Instant coffee". I think I still > slightly prefer "instant", but I don't mind much any more :). Ah, we want a noun that isn't readily confused as an adjective. Suitable terms might include: Instant Jiffy Juncture Moment Occasion Snap Tick ... -Martin
Re: Signals question for S16: IPC / IO / Signals
On Mon, 23 Feb 2009, Timothy S. Nelson wrote: > I have a quick question here. S16 claims to be about IPC, IO, and > Signals. So far, it's mostly about IO. My question is, is it intended > that IPC and/or signals be part of the core, or should they be converted > to addons like Form.pm? Conceptually I think they should all go in add-on(s), however I suspect that when an exception is thrown inside a signal handler, cleanly unwinding the call chain will need special support in the core. That's not to say that methods for setting the signal handler needs to be in the core though, just the low-level code that receives signals and arranges not to leave a (broken) partially-formed call frame in the chain while setting up a call frame to invoke the handler function. -Martin
Re: Comparing inexact values (was "Re: Temporal changes")
On Tue, 24 Feb 2009, Jon Lang wrote: > $y ± 5 # same as ($y - 5) | ($y + 5) > $y within 5 # same as ($y - 5) .. ($y + 5) I suspect that we're running against Huffman here, given the likely usage -- ranges *should* be used at pretty much every floating point "equality" test, whereas "any(-x,+x)" would mostly be useful for expressing solutions to polynomials. Perhaps we could define infix:± as a range generator and prefix:± as a set generator: $y + ±5 # same as ($y - 5) | ($y + 5) (also same as $y - ±5) $y ± 5# same as ($y - 5) .. ($y + 5) -Martin
Re: Comparing inexact values (was "Re: Temporal changes")
On Wed, 25 Feb 2009, I wrote: > $y + ±5 # same as ($y - 5) | ($y + 5) (also same as $y - ±5) > $y ± 5# same as ($y - 5) .. ($y + 5) A further question: should such ranges be [closed], (open) or [half-open)? I would argue for half-open because then exactly one of a set of consecutive ranges will match; back to the original question, I'd only expect one match from: $time ~~ $date-yesterday $time ~~ $date-today $time ~~ $date-tomorrow even if $time falls precisely on midnight. -Martin
Re: r25490 - docs/Perl6/Spec
On Wed, 25 Feb 2009, Timothy S. Nelson wrote: > I'm in favour of retaining the $[ functionality, but lets give it some > name like $*INDEX_BEGINNING or something like that, so that it's quite > long for people to type :). Surely the interpretation of the index should be up to each array-type? role OffsetArray[::ElementType = Object;; int $MinIndex = 1] { is Array; has ElementType @.contents; method circumflex:? [ ] ? (int $index where { $_ >= $MinIndex } ) { return @.contents[$index - $MinIndex]; } } -Martin
Re: Comparing inexact values (was "Re: Temporal changes")
On Thu, 26 Feb 2009, Jon Lang wrote: > asin is not the inverse function of sin, although it's probably as close > as you can get. And even there, some sort of compiler optimization could > potentially be done, replacing the composition of asin and sin (both of > which have the potential to intensify error) with a normalization of the > value into the -pi ..^ pi range (which might also introduce error). Hmmm ... the normal mathematical range of arc-sine is (-π,+π], rather than [-π,+π), especially where complex numbers are concerned: arg(-1) == +π. (Well, so much for consistently using lower half-open ranges.) -Martin
Re: r25490 - docs/Perl6/Spec
On Thu, 26 Feb 2009, Martin D Kealey wrote: > On Wed, 25 Feb 2009, Timothy S. Nelson wrote: > > I'm in favour of retaining the $[ functionality, but lets give it some > > name like $*INDEX_BEGINNING or something like that, so that it's quite > > long for people to type :). > > Surely the interpretation of the index should be up to each array-type? > > role OffsetArray[::ElementType = Object;; int $MinIndex = 1] > { [...] } On Wed, 26 Feb 2009, Larry Wall wrote: > Oops, too late, by about 23 months. Please see S09. Aah yes! The hash-like syntax is much nicer! S09 (http://perlcabal.org/syn/S09.html#User-defined_array_indexing) saith: > User-defined array indexing > > Any array may also be given a second set of user-defined indices, which need > not be zero-based, monotonic, or even integers. Whereas standard array > indices always start at zero, user-defined indices may start at any finite > value of any enumerable type. Standard indices are always contiguous, but > user-defined indices need only be distinct and in an enumerable sequence. But if the indexes are floating point values, do they have error margins? *Should* they have error margins? my @labels{ atan(1)*2, exp(1), (1+sqrt(5))/2 } = < pi e golden-mean >; > To define a set of user-defined indices, specify an explicit or enumerable > list of the indices of each dimension (or the name of an enumerable type) in > a set of curly braces immediately after the array name: > > my @dwarves{ 1..7 }; > my @seasons{ }; > > my enum Months > «:Jan(1) Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec»; > > my @calendar{ Months; 1..31; 9..12,14..17 };# Business hours only Hmmm, that reminds me, I was going to ask about enum types that have implicit modulus: my enum Season «Spring Summer Autumn Winter»; my Season $s = Winter; ++$s; assert($s == Spring); -Martin
Re: r25573 - in docs/Perl6/Spec: . S32-setting-library
On Thu, 26 Feb 2009, pugs-comm...@feather.perl6.nl wrote: > +The exceptions are: > + > + Signal Action R Comment > + -- > + ControlExceptionSigHUPTerm? Hangup detected on controlling terminal > or death of controlling process [...] > + ControlExceptionSigCHLD Ign ? Child stopped or terminated [...] > + ControlExceptionSigURGIgn ? Urgent condition on socket (4.2BSD) [...] > + ControlExceptionSigWINCH Ign ? Window resize signal (4.3BSD, Sun) [...] > +XXX I'm unsure how the actions in the table above can be made to make sense. > The Ign > +actions are already dealt with because %SIG{CHLD}.exception already defaults > to undef. > +The Term action will probably be self-solving (ie. will terminate the > process). The > +others I'm just plain unsure about. XXX That looks a lot like a mangled version of "man 7 signal" from Linux. IMHO the default action shouldn't be specified at all by the Perl standard; it should simply refer to the appropriate external standard. In POSIX the settings "terminate", "ignore", "catch" and "default" have 3½ distinct meanings. For *most* signals "default" is the same as "terminate" (sometimes with a core), but not for all. In particular, for SIGCHLD, if you "ignore" it, the "wait" call will always fail (having delayed until all child processes have exited), whereas if you leave it as "default", your process will still ignore it, but "wait" will work properly. On some implementations SIGUSR1 and/or SIGUSR2 are ignored by default. Core dumps are subject to ulimit controls, even when the signal in question would normally trigger them. -Martin
Re: .map/.reduce with larger arity
On Mon, 9 Mar 2009, Larry Wall wrote: > the only difference between C and C is that you can only use > C at the start of a statement. But we're more liberal about where > statements are expected in Perl 6, so you can say things like: > > my @results = do for @list -> $x {...}; > my @results = (for @list -> $x {...}); > > and either of those is equivalent to: > > my @results = map -> $x {...}, @list; > > I also Officially Don't Care if you use map in a void context. :) (Good.) Maybe we should just treat "map" as a synonym for "for". I'd like to be able to use grep, map, etc in a currying fashion. Can I do: my &square_list := -> $x { $x * $x }.map(); And if so, what is the signature of &square_list ? Maybe that's why there's a difference between "for" and "map" @list = @array.map(&code); &iterator = &code.for($signature); @list = iterator(@list); But I suspect they should logically be the other way around: &iterator = &code.map($signature); @list = iterator(@list); @list = @array.for(&code); -Martin
Re: Junction Algebra
On Mon, 30 Mar 2009, Jon Lang wrote: > Here's another useful one: > > any($x) eqv all($x) eqv one($x) eqv $x > > but: > > none($x) !eqv $x > > That is, applying any, all, or one to a one-item list produces the > equivalent to a single item. For an empty list: any() eqv all() eqv > (). But what about one() and none()? It seems to me that "one" is out of step with the "scalarness" of junctions; it implies that you have to look for two things, firstly that there is some value in the eigenstates that satisfies whatever condition, and secondly that every other value does not. I suspect that the confusion arises because the original intention would have been to have something along the lines of: none === !any something === !all except that "one" doesn't fit the bill as "something". But back to the original question, since "none" is just a funny spelling for "!any", their mutual combination can be flattened accordingly: none($a, any($b, $c)) == none($a, $b, $c) And (given a suitable interpretation of a monadic "none"): all($a, none($b, $c)) == all($a, none($b), none($c)) Question: Or in general, it doesn't matter how many times you mention a simple scalar in an expression, it always has the same value, so that ( $a <= $x <= $b ) == ( $a <= $x && $x <= $b ) always holds true. However I suspect that if $x = any(-1, +1) this may no longer be the case. This would certainly be false: ( $a <= any(-1,+1) <= $b ) == ( $a <= any(-1,+1) && any(-1,+1) <= $b ) Consider if $a and $b are both 0 ... For this to work it seems that the auto-threading logically must reach back to the point where the junction is created, or at least to be tied to the identity of the junction in some way. Which latter would imply that any($a, $b) !== any($a, $b) There must be a logical way out, but how? Any other comments? What about: $x = any(-1,+1); $x < $x and die; # must not happen (same eigenstate must # be used on both sides of '<' ?) $x < $x.eigenstates.any() or die; # matches for "-1 < +1" -Martin
Re: [Fwd: Re: junctions and conditionals]
On Wed, 1 Apr 2009, Richard Hainsworth wrote: > A closer examination of Martin's message indicates that he tends to think > that hitting a junction ought to thread the entire program throughout the > rest of the lifespan of said junction Yes -- and well put, thank-you. The trick is that since conditionals generally force full or partial resolution on junctions, that lifetime won't tend to be very long. Re: Tsa's comment about junctions being "value types". In principle I agree, except that the value semantics are only within the eigenthreads; outside that, they are collections of indeterminate state. Indeterminate states aren't sufficiently "value-like" to justify "constant folding". -Martin
Re: simultaneous conditions in junctions
On Wed, 1 Apr 2009, John Macdonald wrote: > If I understand correctly, (which is by no means assured) a function > call with a junction as an argument generally acts as if it were > autothreaded. So: > > $x = any(1,2,3); > $y = f($x); > > should work like: > > $y = any( f(1), f(2), f(3) ); > > Right? In general yes. However if "f" involves some kind of "truth inversion" then logically f(any(@x)) == all(map.assuming(&f).(@x)) and f(all(@x)) == any(map.assuming(&f).(@x)) I have in mind something like these in the "standard preamble": prefix:«!»(Bool) does(junctive_inversion) prefix:«not»(Bool) does(junctive_inversion) infix:«ne»(String,String) does(junctive_inversion) infix:«!=»(Num,Num)does(junctive_inversion) infix:«!==»(Object,Object) does(junctive_inversion) (Excuse the rather lose syntax, but I hope you get the idea.) -Martin
Re: Why pass by reference?
> Matthew Walton wrote: > > If a user of your API contrives to make it change while you're > > running, that's their own foot they've just shot, because they can > > look at the signature and know the semantics of the parameter > > passing being used and know that if they change the value externally > > before you return Bad Things Could Happen. > On Tue, 16 Jun 2009, TSa wrote: > I agree that the caller is responsible for the constness of the value > he gives to a function. With this we get the best performance. At the language level this is wrong. Programmers are BAD at this sort of thing, unless the compiler *always* has enough to throw a compile-time error, and even then it's dicey because we may defer compilation. It seems to me this is pushing something onto the author of the caller that they shouldn't have to deal with, especially when you consider that the parameter they're passing into the function may come from somewhere else, which hasn't been made -- and indeed CAN'T be made -- to promise not to meddle with the value (note *1). If the compiler can't spot it, how do you expect a fallible human being to do so? If a function requires an invariant parameter then the compiler should ensure that that guarantee is met, and not rely on the programmer to do something that is impossibly hard in the general case. A simple way would be to call $parameter := $parameter.INVARIANT() (*2) on the caller's behalf before calling the function. Conversely, when calling a function where the parameter is declared :rw, the compiler can call $parameter := $parameter.LVALUE() (*3) on the caller's behalf first if it needs to convert an immutable object to a mutable one. (Or throw up its hands and assert that it's not allowed.) If we really expect the optimizer to make Perl6 run well on a CPU with 1024 cores (*4), we have to make it easy to write programs that will allow the optimizer to do its job, and (at least a little bit) harder to write programs that defeat the optimizer. To that end I would propose that: - parameters should be read-only AND invariant by default, and - that invariance should be enforced passing a deep immutable clone (*5) in place of any object that isn't already immutable. -Martin Footnotes: *1: There are many possible reasons, but for example the caller didn't declare it :readonly in turn to its callers because it *did* plan to meddle with it -- but just not by calling this function with its :readonly parameter. *2: Yes I made up "INVARIANT". The trick is that the compiler only needs to insert the call if can't prove the invariance of $parameter, which it *can* prove when: - it arrived in a :readonly parameter; or - it's locally scoped, and hasn't "escaped". In addition the implementation of INVARIANT() could: - return $self for any "value" class; and - return the encapsulated immutable object for the case outlined in the following footnote. Otherwise the default implementation of INVARIANT() would be like deepclone(). (Declaring a "value class" would ideally be shorter than declaring a "container class", but I'm a bit stuck as to how to achieve that. Ideas are welcome...) *3: The LVALUE method produces the sort of proxy object that others have described, but with the reverse function: it acts as a scalar container that can only hold immutable objects, and proxies all method calls to it, but allows assignment to replace the contained object. Calling INVARIANT on such a container object simply returns the encapsulated immutable object. *4: As a generalization, the assumptions floating round that "the compiler will optimize things" just aren't facing reality: programmers are about the worst people when it comes to learning from the past mistakes of others, and future generations of Perl6 programmers will inevitably create evil container classes with no corresponding value classes, and thus most parallelizing optimizations will be defeated. *5: At the language level at least, copying is NOT the enemy of optimization. On the contrary, if you always copy and *never* mutate, that ensures that the compiler can always determine the provenance and visibility of any given datum, and thus has *more* opportunities to avoid *actually* copying anything. And it can parallelize to the full extent of available hardware because it can guarantee that updates won't overlap.
Re: Why pass by reference?
On Fri, 19 Jun 2009, Martin D Kealey wrote: > To that end I would propose that: > - parameters should be read-only AND invariant by default, and > - that invariance should be enforced passing a deep immutable clone >(*5) in place of any object that isn't already immutable. Sorry, typo: that last word should have been "invariant", meaning that it *won't* change, rather than "immutable", meaning that it *can't*. Compilers can rely on invariance to perform a range of very powerful optimizations; immutability is one way to guarantee invariance, but not the only way. -Martin
Re: XOR does not work that way.
On Wed, Jun 24, 2009 at 10:35, John Macdonald wrote: > Which means that short-circuiting is not right here - it must > go through the entire list to determine whether there are zero > true selections, find the first of exactly one true selections, > or die if there are more than one true selections. On Wed, Jun 24, 2009 at 11:10:39-0700, Jon Lang wrote: > Which, I believe, is exactly how XOR short-circuiting currently works: > it short-circuits to false if both sides are true; otherwise, it > returns true or false as usual for XOR and continues on down the > chain. It's not a short-circuit unless you can avoid evaluating at least one arguments at least some of the time. When computing "odd parity" no short circuit is ever possible. When computing "exactly one true" it's only possible if you have at least 3 arguments; having found two that are true, you know the answer is "false" without checking any others. On Wed, 24 Jun 2009, John Macdonald wrote: > Failing to distinguish "zero" from "more than one" makes cases where > xor is of any utility even more rare, it would seem to me (and it's > already quite rare). Which points to a fairly obvious solution: "more than one" isn't just false, it's an exception. So infix:<^^> should return an unthrown exception if both operands are "true". If one operand is already an unthrown exception, that exception should be propagated, and the other operand doesn't need to be evaluated. If one operand is true then return it; otherwise return the right-hand operand (which should be false). This solves both the human expectation ("Would you like wine or beer or juice?" "Beer and juice please" "Sorry...") and the associativity problem: (a ^^ b) ^^ (c ^^ d) == a ^^ (b ^^ (c ^^ d)). -Martin PS: Given that my suggested definition would always return one of the values, could it be an L-value? Should it? Some cool new ways to write obfuscated code: ($a ^^ $b) %= 2
Re: XOR does not work that way.
On Thu, 2 Jul 2009, TSa wrote: > Martin D Kealey wrote: > > This solves both the human expectation ("Would you like wine or beer or > > juice?" "Beer and juice please" "Sorry...") and the associativity > > problem: (a ^^ b) ^^ (c ^^ d) == a ^^ (b ^^ (c ^^ d)). > > I don't understand how the associativity problem is solved when we > use unthrown exceptions to implement the one of n xor. The expression > True && True && True is False without parens but (True && True) && True > evaluates to True Assuming you meant "^^" rather than "&&", then under my proposal, that's not the case. In particular, True ^^ True evaluates to TooManyException. If that exception is implicitly thrown, then that's what you get from the whole expression. If not, TooManyException ^^ Anything doesn't evaluate the right operand at all, and returns the value of the left operand. So you'd get the same answer regardless of whether you put brackets in or not. -Martin
Re: $*CWD and chdir()
On Wed, 19 Aug 2009, Timothy S. Nelson wrote: > ..but Perl is more magic than bash :). Seriously, I can see both > sides of the argument, and I'm leaning towards the $*CWD = chdir idea (as an > option if people want to use it), but I realise that a lot of people are > leaning the other way. So I'll argue for it, but don't care if I lose :). I want both. I can have both. Or in fact all three: $*CWD = "foo";# exception -- $*CWD isn't writable use Cwd :fake; $*CWD = "foo";# OK, faking it use Cwd :chdir; $*CWD = q; # OK, same as {chdir "/tmp"} I wonder if this is becoming the new Perl mantra "use lexically scoped pragmata". perl6 -MCwd=fake ... # legacy behaviour -Martin
Re: unusual invocants
On Wed, 21 Oct 2009, Ben Morrow wrote: > The most important detail here is that the *class* gets to pick which > imported methods need to be wrapped. [but] > What this doesn't fix is that some other code (outside the class) will be > expecting C::x to have T1::x semantics, and some will be expecting it to > have T2::x semantics. If these are contradictory, there is no way to write > an x which works. That's where the 'hats' idea comes in Sounds like going back to static typing -- which does sometimes have some advantages. One way to implement at would be to use proxy objects, which only do one of the roles (by passing them through to the appropriate methods on the original object). This could be done transparently to formal parameters, so that when they're used locally they would dispatch the "expected" method based on the locally declared type for the object. -Martin
Re: r29113 - docs/Perl6/Spec
On Tue, 17 Nov 2009, pugs-comm...@feather.perl6.nl wrote: > +++ docs/Perl6/Spec/S02-bits.pod 2009-11-17 18:37:41 UTC (rev 29113) > @@ -2735,10 +2735,11 @@ > > =item * > > -Complex literals are similarly indicated by writing an addition of > +Complex literals are similarly indicated by writing an addition or > subtraction of > two real numbers without spaces: > > 5.2+1e42i > +3-1i > > As with rational literals, constant folding would produce the same > complex number, but this form parses as a single term, ignoring What happens then to negation of a literal? -5-2i or even - 5-2i Unless that's also a single term, you'd wind up negating the -2i back to +2i, which is almost certainly not what's wanted. Perhaps we could just stick to the "+" form, and add a prefix conjugation operator? Some possible spellings include: conj ⎺ high bar (reminiscent of the mathematical over-bar notation) ⌇ verticle squiggly line ⇅ up-and-down arrow (since it inverts imaginary but not real parts) -Martin
Re: numerics, roles, and naming
On Sun, 14 Mar 2010, Jon Lang wrote: > Ruud H.G. van Tol wrote: > > Did you consider "discrete"? > > I think that "Discrete" could work quite well as the role that > encapsulates the ways in which Integer and Gauss are alike. It may > even be genralizable beyond that, although there might be some discord > between theory and practice. Discrete sounds good to me. Carl Friedrich Gauß was a very significant figure in the development of number theory and many other areas of mathematics; to use his name to label one of his a relatively minor developments doesn't really do him justice. Not that I have a better label in mind though. > (In theory, Boolean is every bit as discrete as Integer is; but in > practice, it has no use for most if not all of the methods in Integer that > pertain to discreteness (factors, remainders, primes, etc.) George Boole also worked in several areas of mathematics. One of those was what he termed "algebra of logic", hence "Boolean algebra" as mathematicians know it now. But what we (programmers) call "Boolean", although in line with his original concept, is a pale shadow of where Boolean Algebra has developed since. In particular there are things call power sets, and a field using set intersection and union over those has the same algebraic properties as the original "algebra of logic", but not with just two "true" and "false" values. So mathematically a "Boolean" value doesn't necessarily behave the same way as a bit, rather it behaves like a structured collection of bits. Treating an integer value as a vector of bits is certainly one such structure. Things like primes over Z(2) are not very interesting, but a field or ring over Z(2)^n does have interesting behaviour that depends on n. So I'm in favour of a "Boolean" role including things such as a vector of bits. I suggest "Predicate" as the name of the role which implements a single true-or-false value (as distinct from a bit, which implements a 0-or-1 value). -Martin
Re: numerics, roles, and naming
On Mon, 15 Mar 2010, Mark J. Reed wrote: > > Anything that can be made into a list is discrete. > > Not quite, since you can create lists whose members belong to > continuous sets, e.g. real numbers. Anything that naturally forms a > list, maybe. A discrete non-finite set is isomorphic to the set of integers. This implies that you can pick an ordering, although perhaps not one that is computational useful. E.g. rational numbers can be mapped onto integers by laying them out in a 2D array, much like Gauß's complex integers, and then walking diagonally in one quadrant. If you have more than one quadrant, take them in turns. Extends to 3D and higher in a logic fashion. But totally useless as a "greater than/equal to/less than" comparison test. -Martin
Re: You never have privacy from your children in Perl 6
> On Mar 27, 2010, at 15:43 , Darren Duncan wrote: > > For example, say you want to define a graph of some kind, and for > > elegance you have a separate container and node and side classes, On Sat, 27 Mar 2010, Brandon S. Allbery KF8NH wrote: > This sounds like a hackaround for an incomplete implementation of ADTs. No, it's simply a reflection that the one-to-one relationship between the attributes of a single storage object is too simplistic to use as the *only* encapsulation boundary. Of course, that points towards having access limits that depend not just on the type, but on the specific object: in Darren's example, nodes should be able to see the details of the edges and faces they're attached to, but probably not any other edges or faces. And definitely not the edges or faces in some completely disconnected mesh or network. A connected mesh or network is a reasonable ADT, but to implement it you're going to want several classes. The mesh-object-as-a-whole is the appropriate encapsulation boundary. If we had a really sophisticated ADT that could represent a "Network", that would indeed solve the encapsulation problem. So what tools are we going to need to build such an ADT? Well, privacy, trust, ... -Martin
Re: A common and useful thing that doesn't appear to be easy in Perl 6
On Wed, 7 Apr 2010, yary wrote: > 2010/4/6 Larry Wall : > > Set(Read | Write) # bogus, R|W is really 3 sets, R, W, and RW! > > Set(Read & Write) # okay, can only represent RW > > Set(A | B) doesn't seem so bogus to me, if what you want is the power > set Hmm, surely a power-set would be written as Set(Set(X,Y,...)) or perhaps more mathematically as 2 ** Set(X,Y,...) -Martin
Re: perl6 operator precedence table
On Thu, 24 Oct 2002, Larry Wall wrote: > It's possible the syntax for substitution should be wrapped around the syntax > for matching, whatever that turns out to be. That strikes me as promising... Going back to Perl5 for a moment, we have substr($str,$start,$len) = $newstr why not simply extend pattern-matching in a similar way to substr, making it an L-value, so that one gets $str ~ /[aeiou]+/ = "vowels($&)" or $str ~ /\d/ {hyper-symbol}= (0) x {size-of-LHS-array}; (hyper, however it's spelt, will have some way for the RHS to reference the LHS, won't it?) -Martin -- 4GL ... it's code Jim, but not as we know it.
Re: perl6 operator precedence table
On Tue, 29 Oct 2002, Damian Conway wrote: > Or one could define a copy-the-invoke method call operator (say, C<+.>): As a rule I prefer to see "safe" operations have short names and "dangergous" operations with longer ones. In this context that means "copy" gets the short name and "in place" gets the longer one. So we should define that methods where possible return new values rather than acting in-place, but define an apply-assignment operator (say C<.=>) to use when you want to act in-place. Of course, the methods can be made aware of this so that they can optimise where appropriate. $str .= chomp; # store result in-place $new = $old . chomp;# return resultant value $str .= lcfirst;# store result in-place $new = $old . lcfirst; # return resultant value $str .= replace( /foo/ -> {'bar'} ); $new = $old . replace( /foo/ => { 'bar' } ); Unfortunately that sits badly with things that "return" two non-scalars (such as "splice" resulting in an portion excised and a remainder) because it means that this assignment operator doesn't return the "resulting value" the way that other assignment operators do. Also having the in-place version return something different from the copy version would be non-obvious to neophites, but that's a problem no matter what notation is used. @excised = @array .= splice($position,$count,@insertions); vs @excised = @array . slice($position,$count); @unexcised = @array . splice($position,$count,@insertions); So, in @a = @b .= grep {/foo/}; should @a be the elements that I contain "foo" or those that I? -Martin
[OT] linguistics and cultural bias?
On Tue, 29 Oct 2002, Larry Wall wrote: > Logically entangle nouns *are* more basic than grade school. Kids are > even sophisticated enough to disambiguate "xor" from "or" by context, > despite the fact that English has no "xor" operator: > > Which do you want? A popsicle or a Mickey Mouse hat? Hmmm... I've heard that this is a culturally driven thing: that whilst people can all disambiguate it, people from different cultures may do so differently In a "western" culture, exclusive-or is the assumed default unless context implies otherwise. But in many Pacific island cultures (*), if one offers "kava or coffee" one would be expected to provide both if answered "yes". -Martin (* This from annecdotal memory of 20 years ago, so I don't vouch that it still applies in any particular culture, but the essential point remains that the disambiguation is not as universal or consistent as may seem to us sitting here in Australasia, USA or Europe, speaking English.)
Re: [RFC] Perl6 HyperOperator List
On Tue, 29 Oct 2002, Larry Wall wrote: > Maybe we should just say that you can put it anywhere that makes sense, > and let the perl parser sort out the sheep from the goats. The basic > rule is that for any op, [op] is also expected in the same place. It would be nice to have a fully generalized set of applicative manipulators. The basic set in applicative languages like Haskell generally includes map, zip, fold and do; from these others can be constructed, but for efficiency in an imperative language we'd probably want a few more like apply and cross-product. It strikes me that [op] is a composition of yet more basic facilities; thus @a [+] @b would be something like map { $_[0] + $_[1]) } zip @a, @b In general it would be nice to be able to make shorthands for arbitrary compositions; eg, with some definition for "zip" that results in the above, one could then go simply @a zip:+ @b which while not as short as @a [+] @b, is more obviously a specific instance of a more general construct. -=*@*=- Apropos substitution, I still like the idea of having matched sub-strings as magic L-values. I think the ".=" assignment operator makes this a lot more feasible than simply using a straight assignment, which as Larry mentioned before would be problematic with its right-to-left evaluation. But for an assignment operator that needn't necessarily be the case, and indeed implicitly is not the case. Using the ".=" operator, we could have: Perl5: Perl6: $a =~ s/\d/X/; $a ~ /(\d)/ = "X"; $a =~ s/\d/X/g; $a ~ /(\d)/ [=] "X"; $a =~ s/\d/ ($&+1)%10 /eg; $a ~ /(\d)/ [.=] { ($_+1)%10 }; Or if you don't like switching from = to .=, just stick with ".=" and define that ".literal" always returns the literal, after evaluating and discarding the LHS, and ".=literal" likewise evaluates the LHS, then sets the LHS to the literal value. > So if the user defines a postfix:! for factorial, they automatically get > _[!] for that as well. postfix vs infix ... mumble ... parsing nightmare ... mumble ... > I think we could also allow > > @a [??] @b [::] @c > > But it's not clear whether we can parse > > @a = [undef][...] What about $a = $x lazy:? $y : $z so that $a is thus an object which when stringified (or numified or whatever) chooses whether it's $y or $z, but not until? -Martin
Re: perl6 operator precedence table
On Fri, 25 Oct 2002, I wrote: > > why not simply extend pattern-matching in a similar way to substr, making it > > an L-value, so that one gets > > > > $str ~ /[aeiou]+/ = "vowels($&)" > > > > or > > > > $str ~ /\d/ {hyper-symbol}= (0) x {size-of-LHS-array}; On Thu, 24 Oct 2002, Larry Wall replied: > Problem with that...the replacement argument has to be lazy, and currently > the RHS of an assignment is actually evaluated before the left. You'd > really need something more like > > $str =~ /\d/ = { 0 } How about just $str =~ /\d/ .= "0" or $str =~ /\d/ .= { 1 + $_ .& 7 } in which using "." (apply) would force a fetch of the LHS in advance of evaluating the RHS. And for global-replace we could use the vector/hyper notation: $str =~ /\d/ [.=] "0" > However, I think readability suffers without a hint on the front what > you're trying to do. We don't in general have a "let" on the front of assignment statements; why should this type of assignment be any different? (Do we want a "let" keyword? Personally I don't think so, but what do others think?) -Martin -- How to build a Caspian Sea oil pipeline - step one: get elected president...
Re: String concatentation operator
On Mon, 2002-11-18 at 18:10, Dave Whipp wrote: > Why do we need to use preemptive threads? If Parrot is a VM, then surely > the threading can be implemented at its level, or even higher. And what about *lower*? Like down among the CPUs? I want Perl to run 128 times faster on a 128 CPU machine... now I know that's not entirely realistic, but it should be able to run at least say 60 times faster. It's not that we necessarily want *preemptive* threads, but if we can't do that, we certainly can't do multiprocessor threads. -Martin
RE: Unifying invocant and topic naming syntax
On Wed, 2002-11-20 at 15:01, Brent Dax wrote: > We need that capability if we're going to have lexically-scoped exports: Whilst it would be useful for pragmatic modules to access anything and everything in the current compilation scope, I submit that access to dynamic scope should (in general) be more closely controlled... and of course the former can be used to implement the latter: use visible '$topic'; no visible '$_'; -Martin
Re: String concatentation operator
On Thu, 2002-11-21 at 06:57, Mark Biggar wrote: > Martin D Kealey wrote: > > I want Perl to run 128 times faster on a 128 CPU machine... now I know > > that's not entirely realistic, but it should be able to run at least say > > 60 times faster. > > Amdahl's law applies here: "no amount of paralellism will speed up > an inheirently sequential algorithm" True in the abstract, but in practice in most languages an awful lot of algorithms that I inherently sequential get serialized by the compiler because it can't tell it's safe to do otherwise. This is where pure-functional or applicative languages can have a big performance win - because the compile almost alway I see that things are safe to parallelize. -Martin
RE: Unifying invocant and topic naming syntax
On Thu, 2002-11-21 at 20:11, Brent Dax wrote: > Are you suggesting this? > > if($error) { > use visible '&croak'; > require Carp; > import Carp: 'croak'; > croak($error); > } No - that would be pointless as well as error-prone. My idea of "visible" is that it would make a lexically scoped thing accessible to an inner dynamic scope at run-time. By default that would only apply to $_, but the mechanism should be generalisable to any name. -Martin
L-valueness of Arrays vs. Lists
On Tue, 11 Feb 2003, Michael Lazzaro wrote: > What is the utility of the perl5 behavior: > > \($a,$b,$c) > > meaning > > (\$a, \$b, \$c) > > Do people really do that? ... Can someone give an example of an actual, > proper, use? Yes, I've used it like this: for (\($a,$b,$c)) { $$_++; } to be sure that it works on all versions, since for ($a,$b,$c) { $_++; } works differently on different versions. (Actually, I don't have an old-enough version on hand to check just when that was, so it must have been 5.004 or before.) This change didn't start to bite me until P5.6.0, when "values %HASH" became an Lvalue too, whereupon for ( values %HASH ) { s/^prefix//; ... } ... do something else with %HASH stopped working. So, I would urge making as many things as possible Lvalues (and magical references) right from the start of P6, just so as we don't break things by making them so later. -Martin -- Help Microsoft stamp out software piracy: give Linux to a friend today...
Re: Arrays, lists, referencing
I would like to chip in in favour of the "list is value, array is container" side of the argument. However I think that needs clarifying. A reference is a value; the thing it refers to is a container. An anonymous container is a container with no references from any symbol table. It can lose its anonymity by creating such a reference. A list is an ordered set of references to (normally anonymous) containers. An array is a container that contains a list. When created, an array contains the empty list. The operations push, pop, shift, unshift, extend, truncate and element auto-vivify replace the value in the array with another value similar to the old one. Assignment replaces the value in the array with an entirely new value. Operations on individual elements of an array do not affect the value of the array, just the values in the containers that the array's list members refer to. Possible definition: Except for "obvious" arrays and hashes (those involving "@" or "%" in the expression), anything evaluated inside a list in R-value context is itself in reference context. Named arrays and hashes are in flatten-to-reference-to-member context. Anything evaluated inside a list in Lvalue context is itself in reference context. Assignment to a list deferences successive elements of each side. Passing a list as parameters dereferences each element unless the prototype says otherwise. Almost all of these containers are either elidable at compile time, or will be needed "soon" anyway -- eg, as elements in the formal parameter list; so there's no practical cost to this definition. On a related topic... I like to be able to program in a "pure functional" mode as much as possible, mainly because it's the easiest to prove correctness, but also because it also offers the greatest scope for compile-time optimisation. What I would like is for the language to enable as many compile-time optimisations as possible, by making the optimisation-friendly choices the shorter easy-to-type defaults. One of those, rather inobviously, is choosing pass-by-value rather than pass-by-reference. And rather deeper pass-by-value than the sort of list I've talked about above: a list would be a set of actual values, not a set of references to containers containing values. And we could extend this to things other than arrays/lists. It's important to understand that I'm talking about the semantics of the language, not the implementation. The point is that the implementation is still free to pass by reference when it can be sure that the receiving function won't fiddle with it. That can be guaranteed if you can see (or infer) all the way down to the leaf function calls at compile time. (This gets complicated at trust boundaries, but we can work on that.) One of the things I found most irksome moving from C++ to Java was that Java took away both "pass object by value" AND "pass object by const reference". Couple that with some rather bad choice of "value" vs "container" in the standard class library, and the result was that one had no way to be sure that an object wouldn't get modified once you handed a it over as a parameter or referent to some random method. Since then languages such as ECMAscript have copied that behaviour, and it seems that P6 is looking more and more like a clone of that language ... and that worries me. I would like to argue in favour of "pass by value" to be the default in the absence of some explicit prototype, because it allows greater type-safety, and because the opposite default interacts badly with out-of-order execution such as parallelism, and bars some optimisations that can be applied to closures. (We do want Perl to run fast on parallel hardware, don't we?) The relationship to the array/list thing is this: that it's not just pass-by-value to functions and methods, it's about implicit R-valueness in any context that doesn't absolutely require L-valueness. All this is orthogonal to the concept of "object": in C++ "an object" can be used to implement either a value (such as "string") or a container (such as "vector"); it would be nice to be able to do this in P6 too. -Martin PS: sorry for the long post...
Re: Suggested magic for "a" .. "b"
On Wed, 28 Jul 2010, Darren Duncan wrote: > I think that a general solution here is to accept that there may be more > than one valid way to sort some types, strings especially, and so > operators/routines that do sorting should be customizable in some way so > users can pick the behaviour they want. > > The customization could be applied at various levels, such as using an > extra argument or trait for the operator/function that cares about > ordering, That much I agree wholeheartedly with, but ... > or by using an extra attribute or trait for the types being sorted. ... puts us back where we started: how do we cope if the two endpoints aren't tagged with the same attribute or trait or locale? In any case I'd much rather prefer that the behaviour be lexically scoped, with either adverbs or pragmata, not with the action-at-a-distance that's caused by tagging something as fundamental as a String. Yes sometimes you want the behaviour of your range to mimic the locale of its operands, but then it should be explicit, with a trait that also explicitly selects either the left or right operand to extract the locale from. And probably throw an exception if they aren't in the same locale. If you don't specify that you want locale-dependent behaviour then the default action should be an unthrown exception unless both endpoints are inarguably comparable, so IMHO that pretty much rules out any code-points that are used in more than language, save perhaps raw ASCII. And even then you really should make an explicit choice between case-sensitive and case-insensitive comparison. > When you want to be consistent, the behaviour of "cmp" affects all of the > other order-sensitive operations, including any working with intervals. Indeed, the range constructor and the cmp operator should have the same adverbs and share lexical pragmata. > So then, "a" cmp "ส้" is always defined, but users can change the > definition. I take the opposite approach; it's always undefined (read, unthrown exception) unless the user tells us how they want it treated. That can be a command-line switch if necessary. To paraphrase Dante, "the road to hell is paved with Reasonable Defaults". Or in programming terms, your reasonable default is the cause of my ugly work-around. -Martin
Re: Smart match isn't on Bool
On the one hand, I've had 25 years of being annoyed about the idiom if foo() == True ... So I'd be delighted if P6 were to treat that case as a fatal compile-time error. And given that "==" are "!=" are just funny ways of writing "!xor" and "xor", that prohibition could reasonably be extended to all statically-typed expressions (not just constants), with the error message suggesting the use of "!xor" or "xor" instead. On the other hand it feels it'd be wrong if foo() ~~ bar() simply ignored the value of one of its operands based on the type of the other. Overall I'd rather see a solution that factors out the implicit "last" from the implicit "$_ ~~". My feeling is that "if" and "when" should be for the implicit "last", since they're all alphabetic tokens; then it's just a case of deciding how to spell the contextualizer. The most obvious would be if == VALUE-TO-MATCH {...} if ~~ VALUE-TO-MATCH {...} when == VALUE-TO-MATCH {...} when ~~ VALUE-TO-MATCH {...} however I'm not sure if that conflicts with any prefix:<~~> or prefix:<==>, and it also conflicts with Huffmanizing the implicit match to something shorter than the explicit comparison. One possibility is to make all options explicit: if= VALUE-TO-MATCH{...} # no implicit last if? BOOLEAN-EXPRESSION{...} if~ VALUE-TO-SMARTMATCH {...} when= VALUE-TO-MATCH {...} # implicit last when? BOOLEAN-EXPRESSION {...} when~ VALUE-TO-SMARTMATCH {...} and then make bald "if" and "when" be DWIMmy shorthand. Oh, and then "A ~~ B" just works like "?! (A) xor B", if B is a Bool. -Martin PS: I also considered some other possibilities, but I don't like them as much: if -> VALUE-TO-MATCH {...} when -> VALUE-TO-MATCH {...} -> if VALUE-TO-MATCH {...} -> when VALUE-TO-MATCH {...} .if VALUE-TO-MATCH {...} .when VALUE-TO-MATCH {...} ==> if VALUE-TO-MATCH {...} ==> when VALUE-TO-MATCH {...}
Re: Tweaking junctions
I have to admit to feeling uneasy about the whole action-at-a-distance effect that junctions are capable of producing. They sit around pretending to be a scalar, only to pop up and wreak havoc with ones expectations of linearity when you're not expecting it. That unexpected-action-at-a-distance is somewhat mitigated by autothreading functions where the junction is presented as a direct parameter, but being able to defer a junction by putting it inside an aggregate seems like asking for trouble unless we make sure that it behaves as much like an ordinary scalar as possible when it does finally get collapsed. I think we need to decide whether junctions are just about flow control, or are more generalized parallel data handling, typified as a way of handling sets. If it's about parallel data handling, then we have to be prepared to (notionally) fork the entire rest of the runtime, even as far as having a definition of what return value the parent process sees (from "exit") when those threads are implicitly collapsed at termination. And deciding what happens when, in the process of autothreading junction A, you wind up collapsing junction B in different ways (including perhaps not collapsing it)? Right now I don't think we're up for all that. For the sake of flow control, do we have a formal algebra of how we apply distributive rules so that all the elements of the resulting junction are booleans and the result of the collapse is "obvious"? In the simple cases it's (supposedly) obvious: $foo == ($bar | $zot) === ($foo == $bar) | ($foo == $zot) But what about: $foo != ($bar | $zot) === not($foo == ($bar | $zot)) === not(($foo == $bar) | ($foo == $zot)) === (not($foo == $bar)) & (not($foo == $zot)) === ($foo != $bar) & ($foo != $zot) Moreover, what about: $foo < ($bar | $zot)=== ($foo < $bar) | ($foo < $zot) versus: $foo < ($bar | $zot)=== not($foo >= ($bar | $zot)) === not(($foo >= $bar) | ($foo >= $zot)) === (not($foo >= $bar)) & (not($foot >= $zot)) === ($foo < $bar) & ($foo < $zot) In short, in order to avoid unexpected action at a distance, it's logical to invert the junction type, but in doing so you hit some very nasty corner cases. How do you know whether a function is saying "X has property Y" or "X does not have property ~Y" ? Which of "Y" or "~Y" are we talking about? It seems fair enough to infer that equality comparison is "Y" rather than "~Y", but any other sort of comparison is fraught. This leads me to the conclusion that collapsing a junction over an ordered comparison should fail in the same way that an ordered comparison involving complex numbers or vectors should fail (or more generally, an ordered comparison of any aggregate should fail unless the aggregate type defines some sensible ordering; there should be no "default"). Indeed, the whole notion of autothreading a junction over an arbitrary function (to produce a boolean that can be used for flow control) starts to sound fishy: how do we decide whether a given function should be treated like "==", where the distributive rule produces the same junction type, or like "!=", where the distributive rule produces the inverse junction type? Or do we not invert junctions, and run the risk of unexpected action-at-a-distance instead? -Martin
Re: Tweaking junctions
On Thu, 28 Oct 2010, Damian Conway wrote: > The apparent paradox ... is due to the assumption (employed in the > second interpretation) that < is identical to !>=. Certainly that is > true for simple scalar numbers, but not always for vector types such > as tuples, sets, bags, complex numbers...or junctions. > That doesn't make either < or !>= intrinsically invalid on vector types > (though they obviously are inappropriate for *some* vector types); it just > means you can't reasonably treat the two operators as universally > interchangeable, just because they sometimes are. Well, I think returning or throwing an "Unordered" exception would be the appropriate way to handle those, both for complex numbers and for junctions. Anyone who thinks they're dealing with real numbers will reasonably expect "<" and "!>=" to be the same, and a junction can masquerade as anything (within each thread), including a real number. And what about when that difference is wrapped up inside a function? In other words, what's wrong when I expect the following two snippets to work the same way? A: sub anything_is_broken($subject) { grep { ! .test() } $subject.parts() } if anything_is_broken($subject) { fail($subject) } else { pass($subject) } B: sub everything_is_working($subject) { ! grep { ! .test() } $subject.parts() } if everything_is_working($subject) { pass($subject) } else { fail($subject) } Why should it make a difference whether $subject is a junction? > In summary, the "problem" here seems to be that, algebraically, > junctions don't behave exactly like non-junctions. Which is true, but no > more a problem than the fact that, algebraically, complex numbers don't > behave exactly like non-complex numbers, or that sets don't behave > exactly like non-sets, or that Rats don't behave exactly like Nums, > which don't behave exactly like Ints, which don't behave exactly like > ints either. When you're talking about built-in operators, that's plausible, because by looking for "!" in the operator name there are ways to DWIM-or-throw-an-exception. That's not true for user-defined functions, so I think the real problem is that the parallelizing of the expression that contains a junction may not be "obvious" at the point where it happens. Hmmm maybe one way to improve that might be to say that you can't put a junction into an untyped scalar, or indeed in any variable that isn't explicitly marked as "this thing might contain a junction". That would apply, as now, to function parameters and returns, but also to variables and aggregate members; indeed, *everywhere*. > And, of course, that's why Perl 6 has strong typing. So that, when > these differences in behaviour do matter, we can specify what kind(s) > of data we want to allow in particular variables, parameters or return > slots...and thereby prevent unexpected kinds of data from sneaking in > and violating (un)reasonable expectations or inducing (apparent) > paradoxes. :-) I don't think strong typing is enough, because we explicitly mask the application of type constraints by autothreading. Each thread sees a thing with the type it expects, but the problem comes when the threads are recombined; the result often won't be what's expected. Don't get me wrong, I think Junctions are a really clever way of writing concise conditional expressions, but I think algebraic consistency is more important than clever conciseness. -Martin
Re: exponentiation of Duration's
On Wed, 17 Nov 2010, Richard Hainsworth wrote: > Once a number has been generated, viz., by obtaining a duration, that number > can be manipulated however necessary. The interpretation of the number is a > matter for the programmer, not the language designer. All true. However I'd argue that you can very easily obtain a bare number as my $plain_number = $duration / $one_time_unit which makes it explicit that you're stripping the dimentionality. Then you can square it or whatever to your heart's content. Dimensioned numbers as restrictive types are useful, for uncovering bugs, including sometimes latent ones in ported code. Duration is a fairly clear example of a dimensioned quantity, and I think we should think twice about abandoning its dimensionality, and the restrictions that implies. -Martin
Re: Encapsulating the contents of container types
On Fri, 9 Sep 2011, Carl Mäsak wrote: > Patrick Michaud said something (I think AFK) that seems essential to > me: the non-rw-ness of these objects isn't a trait of *the object > itself*, it's a trait of *the context in which the object is used*. In one sense that is true, but if that's the only kind of constancy that gets implemented, then it's only half the story. It is of course useful to be able to send a "value" to a sub and know that it won't be mangled when the sub returns, and you do get that from the "const reference" approach that's implied by Patrick's comment. But it's also useful, when in the sub, to know that the someone else won't mess with a "value" while you're working with it. I can't see any way to enforce that without constancy being a feature of the object rather than the reference to it. Moritz Lenz wrote: > I think we should consider the implications of > immutability-all-the-way-down before we jump to any conclusions. In > particular list cases where typical Perl 5 code fails when ported to Perl > 6. Perhaps if we could tag the type/class/pmc/whatever when it's constructed as to whether it defaults to r/o or r/w? Hence things like file handles would be r/w by default, and most other things would be r/o. Actually, I'm inclined to think that r/o vs r/w for sub params is a bit of a blunt instrument. What about the option of treating a "r/w" param as a shorthand for both an r/o param AND an r/o return? So in effect, changes to the "container" don't take effect until after the sub returns. (BTW this would have a lot of benefits for auto-threading code.) -Martin
Re: [perl6/specs] ff11f1: define %%; clarify that % is not quantmod
Out of curiosity, I followed this and read through "Str". When I got to the section on "sprintf", I found a few things I think need attention. 1. There isn't any description what the flags do, in particular 'v', which seems to be a P6 enhancement. 2. Not mentioned are 'hh' (native char), 'j' (native maxint_t) and 'l' (applied to 's' and 'c', native wchar_t). 3. Logically the 'p' conversion applied to an Object should return the object identity (.id or whatever that's called now), though applied to non-objects it should probably still throw an exception. 4. In keeping with named parameters, it seems to me that the 'index' should be extended to allow a name rather than just an integer. Obviously that would need the name to be disambiguated by some punctuation such as <> or «». 5. And pretty please could we have infix:<%>(Str,Capture) as an alias for sprintf? (Not that I'm normally a Python fan, but that feature has a particularly wholesome appeal about it.) -Martin On Sun, 25 Sep 2011, nore...@github.com wrote: > Date: Sun, 25 Sep 2011 17:33:22 -0700 > From: nore...@github.com > To: perl6-language@perl.org > Subject: [perl6/specs] ff11f1: define %%; clarify that % is not quantmod > > Branch: refs/heads/master > Home: https://github.com/perl6/specs > > Commit: ff11f19331bf30327cf729a0f5c9c349caa231c7 > > https://github.com/perl6/specs/commit/ff11f19331bf30327cf729a0f5c9c349caa231c7 > Author: Larry Wall > Date: 2011-09-25 (Sun, 25 Sep 2011) > > Changed paths: > M S05-regex.pod > > Log Message: > --- > define %%; clarify that % is not quantmod > > ingy++ requested a method of stopping optionally after the separator, > so that's now %% (with some notion of "evenly divisible" in some kind > of loose sense). (Note, if you want to require the separator at the > end, don't use this construct, just use [x ',']* or such. > > sorear++ requested clarification: % (and %%) are not really quantifier > modifiers; they modify a quantified atom to insert requirements > between each iteration of that quantified atom. Hence any quantifier > may still take an additional control quantmod in addition to a separator. > > > Commit: 6d7f9f1ad5f42fe3e14d44a10834cda869643cc7 > > https://github.com/perl6/specs/commit/6d7f9f1ad5f42fe3e14d44a10834cda869643cc7 > Author: Larry Wall > Date: 2011-09-25 (Sun, 25 Sep 2011) > > Changed paths: > M S32-setting-library/IO.pod > M S32-setting-library/Str.pod > > Log Message: > --- > Merge branch 'master' of github.com:perl6/specs > > > Compare: https://github.com/perl6/specs/compare/d7b5637...6d7f9f1 >
Re: Setting private attributes during object build
> Damian: > > The whole point of having BUILD() is to separate allocation > > concerns from initialization concerns. On Thu, 2 Feb 2012, yary wrote: > And that's not so good, because it forces BUILD to be used for > initialization, and precludes initializing private attributes anywhere > else, like a "bless" called from the "new" method. Err, isn't that the point: BUILD is for initialization, and bless is for allocation? Except that "bless" also does pass-through for to the initializers, which confuses the mental model. Well, if it's going to do that, perhaps it could take just one parcel parameter? (I do find the notion of an inheritable "constructor" a bit odd, upside-down even. However one of the things I *like* about Perl5 is that a class's object factory doesn't have to be called "new"; instead it can have a name that's natural to the domain of the object: File.open, Socket.listen, Process.run, Timer.start, etc. And object factories can be "instance methods" too: IO.dup, Socket.accept, String.split, etc.) The idea of BUILDALL taking care of the hierarchy and each BUILD just plucking out the named args it needs is quite elegant, but there will invariably be corner cases where it doesn't fit, particularly if one mixes in unrelated classes that conflict on their parameter names. And yet, overriding BUILDALL in an inheritable fashion also seems wrong. One could revert to the Perl5 and C++ way of doing things: explicitly calling up the constructor chain. But then how do you make it clear that BUILDALL is NOT required? Is there an answer to this conundrum? -Martin
Re: How to make a new operator.
On Thu, 22 Mar 2012, Carl Mäsak wrote: > Jonathan Lang (>>), Daniel (>): > >> 1, 2, 4 ... 100 # same as 1,2,4,8,16,32,64 > > > > That last one doesn't work on Rakudo :-( > > And it never will. Note that 100 is not a power of 2, and that the goal > needs to match exactly. This is because smartmatching is used, not some > other comparison. The sequence will continue to generate numbers until the > number 100 is generated, which never happens. Rakudo loops forever on this > one, as per spec. Hmmm, so it's likely that most times you get a Num rather than an Int or Rat, those won't stop either? 1, 7 / 6.0 ... 2 1, sqrt(2), 2 ... 8 Question: do we support 1, 2i, -4 ... 256 > If you're wondering why things are factored in this way, it's because > previous versions of the spec that tried to special-case 100 to work in > cases like the above, ended up not working out. It turned out that the > unification of infix:<...> and smartmatching was what did work. It has the > slight drawback that we have to educate users to write * >= 100 instead of > 100 in the case of not-exactly-matching goal states. But it's still a net > win, because this unified semantics works better than anything we had > before. Sounds to me like AscendingArithmeticIteratorInclusiveTerminalSmartMatch could do the same thing as normal SmartMatch except when the LHS is an IteratorOf{X} and the RHS is an {X}, for X in {Int, Rat, Num} and possibly other comparable (orderable) types, when ">" would be implied. Likewise for AscendingArithmeticIteratorExclusiveTerminalSmartMatch (">=") DescendingArithmeticIteratorInclusiveTerminalSmartMatch ("<") and DescendingArithmeticIteratorExclusiveTerminalSmartMatch ("<="). -Martin
Re: [perl6/specs] 5277fe: Add expmod and is-prime as built-ins in Int
On Wed, 19 Sep 2012, GitHub wrote: > Log Message: > --- > Add expmod and is-prime as built-ins in Int > +Returns True if C<$x> is known to be a prime, or is likely to be a > +prime based on a probabilistic Miller-Rabin test. (The optional > +argument tells how many times to iterate the probabilistic test, > +if such is necessary.) > + > +Returns False if C<$x> is known not to be a prime, or is unlikely to > +be a prime after probabilistic testing. Isn't Miller-Rabin definitive when it disproves primality? In which case the probabilistic qualifier in the last paragraph isn't needed. Or is this just to allow that some better (presumably faster or more probable) non-deterministic primality test might be used in the future? (Though Miller-Rabin is already pretty fast, so there seems little reason not to incorporate it as part of any future test.) But in that case, we should be saying up front that the test might change. -Martin
Re: Grammars and biological data formats
Hmmm, what about just implementing mmap-as-string? Then, assuming the parsing process is somewhat stream-like, the OS will take care of swapping in chunks as you need them. You don't even need anything special to support backtracking -- it's just a memory address, after all. -Martin On Thu, 14 Aug 2014, Fields, Christopher J wrote: > Yeah, I'm thinking of a Cat-like class that would chunkify the data and check > for matches. > > The main reason I would like to stick with a consistent grammar-based > approach is I have seen many instances in BioPerl where a parser is > essentially rewritten based on its purpose (full parsing, lazy parsing, > indexing of flat files, adding to a persistent data store, etc). Having a > way to both parse a full grammar but also subparse for a specific token/rule > is very handy, and when Cat comes around even more so. > > Chris > > Sent from my iPad > > > On Aug 14, 2014, at 6:40 AM, "Carl Mäsak" wrote: > > > > I was going to pipe in and say that I wouldn't wait around for Cat, > > I'd write something that reads chunks and then parses that. It'll be a > > bit more code, but it'll work today. But I see you reached that > > conclusion already. :) > > > > Lately I've found myself writing more and more grammars that parse > > just one line of some input. Provided that the same action object gets > > attached to the parse each time, that's an excellent place to store > > information that you want to persist between lines. Actually, action > > objects started to make a whole lot more sense to me after I found > > that use case, because it takes on the role of a session/lifetime > > object for the parse process itself. > > > > // Carl > > > > On Wed, Aug 13, 2014 at 3:19 PM, Fields, Christopher J > > wrote: > >> On Aug 13, 2014, at 8:11 AM, Christopher Fields > >> wrote: > >> > >>>> On Aug 13, 2014, at 4:50 AM, Solomon Foster wrote: > >>>> > >>>> On Sat, Aug 9, 2014 at 7:26 PM, Fields, Christopher J > >>>> wrote: > >>>>> I have a fairly simple question regarding the feasibility of using > >>>>> grammars with commonly used biological data formats. > >>>>> > >>>>> My main question: if I wanted to parse() or subparse() vary large files > >>>>> (not unheard of to have FASTA/FASTQ or other similar data files exceed > >>>>> 100’s of GB) would a grammar be the best solution? For instance, based > >>>>> on what I am reading the semantics appear to be greedy; for instance: > >>>>> > >>>>> Grammar.parsefile($file) > >>>>> > >>>>> appears to be a convenient shorthand for: > >>>>> > >>>>> Grammar.parse($file.slurp) > >>>>> > >>>>> since Grammar.parse() works on a Str, not a IO::Handle or Buf. Or am I > >>>>> misunderstanding how this could be accomplished? > >>>> > >>>> My understanding is it is intended that parsing can work on Cats > >>>> (hypothetical lazy strings) but this hasn't been implemented yet > >>>> anywhere. > >>>> > >>>> -- > >>>> Solomon Foster: colo...@gmail.com > >>>> HarmonyWare, Inc: http://www.harmonyware.com > >>> > >>> Yeah, that’s what I recall as well. I see very little in the specs re: > >>> Cat unfortunately. > >>> > >>> chris > >> > >> Ah, nevermind. I did a search of the IRC channel and found it’s > >> considered to be a ‘6.1’ feature: > >> > >>http://irclog.perlgeek.de/perl6/2014-07-06#i_8978974 > >> > >> It is mentioned a few times in the specs, I’m guessing based on where it’s > >> thought to fit in best. For the moment the proposal is to run grammar > >> parsing on sized chunks of the input data, which might be how Cat would be > >> implemented anyway. > >> > >> chris > >> >
Re: [perl6/specs] 40163b: reverse associativity on R ops
Reversing the associativity makes sense, but having equal precedence for operators with differing associativity sounds -- as you say -- like madness. Even having non-associative mixed with either-sided-associative sounds like a problem. In general, perhaps we should forbid equal precedence with differing associativity? Which then would mean that R would have to tweak the precedence slightly, to avoid an implicit infraction. So perhaps we could have a rule that meta-ops generate new operators of marginally looser precedence than the originals? -Martin On Sun, 29 Mar 2015, GitHub wrote: > > Branch: refs/heads/master > Home: https://github.com/perl6/specs > Commit: 40163b8cab714f0588c5e62cc7b181d5c2272b80 > > https://github.com/perl6/specs/commit/40163b8cab714f0588c5e62cc7b181d5c2272b80 > Author: TimToady > Date: 2015-03-29 (Sun, 29 Mar 2015) > > Changed paths: > M S03-operators.pod > > Log Message: > --- > reverse associativity on R ops > > This seems slightly less unintuitive than the old semantics.
RE: "All classes imply the existence of a role of the same name."
> -Original Message- > From: chromatic [mailto:[EMAIL PROTECTED] > We are trying to avoid the "java.lang.String is Final" > problem here in various ways. One of them is not allowing > library designers to mark things as final. Overloading "final" was Java's rather inept attempt to define objects with value semantics rather than container semantics (*1). I would be in favour of P6 using some much more explicit way of marking that distinction. And using shorter Huffman coding for "value" than for "container". And work nicely with "compound literals". And still DWIM. :-) I'm not entirely convinced that just tagging stuff with ":rw" or ":ro" is the right way to go; it has too coarse a granularity, so it misses opportunities for optimization. Using "const" works fine in C++ where pass-by-value is the default (or at least, has shorter huffman coding) and you get almost-reasonable copy constructors generated for you. But as we're currently defining Perl6, anything that's an object is passed by reference by default (*2), and object aren't actually "inside" other objects, merely referenced by them (*3). A "const" parameter in C++ lets you pass something to a function and the function promises not to modify it; what's missing (from C++) is the ability for the caller to promise not to modify it either. Likewise in P6 we have no way to pass a "value" object to a sub and at the same time make a promise to that sub that the "value" won't change under it. Or put another way, we have no way to tell the sub that it doesn't have to take a copy to be sure it won't change while it's using it. There are potentially enormous optimisation benefits if you know that an object is immutable (for a start, you never have to copy it), but even with lesser declarative guarantees, in some circumstances you can infer actual immutability, so both types of declarations are useful. I'd like to see separate, clear: - declarative separation of "value" and "container"; - implicit conversion between the two; - promises BY functions that their parameters won't be changed when it returns; - promises TO functions that their parameters won't be changed while they're working with them. In a certain sense doing "values" is easy: simply make a class that has no mutators, sets all its fields in its constructor, and where a field references another object, require that that object too must likewise be a "value". The hard bits include: - getting the programmer to go to the trouble (making the writing of value classes easier for the programmer than writing container classes); - extracting and wrapping "values" from "container" classes, if the container object isn't implemented simply as a singleton reference to a value object (and there may be good efficiency reasons for this too: think "String" vs "StringBuf" in Java). -Martin (*1: At least that one works; is you want to see something that doesn't know whether it's a value or a container, have a look at the ugliness that is java.util.date.) (*2: While primatives still get passed by value. This is of course how Java does it, and indeed pretty much every mainstream OO language created since 1990. Which explains a lot about what's wrong with Java, and software engineering in general: design-by-contract has been reduced to design-by-approximate-guideline-if-you-feel-like-it.) (*3: Compact types not withstanding) --- Have you seen our website? http://www.vodafone.co.nz Manage Your Account, check your Vodafone Mail and send web2TXT online: http://www.vodafone.co.nz/myvodafone CAUTION: This correspondence is confidential and intended for the named recipient(s) only. If you are not the named recipient and receive this correspondence in error, you must not copy, distribute or take any action in reliance on it and you should delete it from your system and notify the sender immediately. Thank you. Unless otherwise stated, any views or opinions expressed are solely those of the author and do not represent those of Vodafone New Zealand Limited. Vodafone New Zealand Limited 20 Viaduct Harbour Avenue, Private Bag 92161, Auckland 1030 Telephone + 64 9 355 2000 Facsimile + 64 9 355 2001
RE: "All classes imply the existence of a role of the same name."
object, and acts as a proxy for all other method calls. Whichever method is used, VALUE() does the corresponding reverse -- either it recursively clones an object with container semantics changing the type of each member to a constant value type, or it simply extracts the reference member. Either way, calling .VALUE() on a value object simply returns SELF. Option (a) is really only useful if you know how deep to go, which means you have to have seen the "container" class definition (and possibly have derived the "value" class automatically). So it makes sense to associate these two approaches with the suggested Value and Class keywords. -Martin (Or you could call them CONSTANT and VARIABLE I suppose; the names aren't important at this stage.) --- Have you seen our website? http://www.vodafone.co.nz Manage Your Account, check your Vodafone Mail and send web2TXT online: http://www.vodafone.co.nz/myvodafone CAUTION: This correspondence is confidential and intended for the named recipient(s) only. If you are not the named recipient and receive this correspondence in error, you must not copy, distribute or take any action in reliance on it and you should delete it from your system and notify the sender immediately. Thank you. Unless otherwise stated, any views or opinions expressed are solely those of the author and do not represent those of Vodafone New Zealand Limited. Vodafone New Zealand Limited 20 Viaduct Harbour Avenue, Private Bag 92161, Auckland 1030 Telephone + 64 9 355 2000 Facsimile + 64 9 355 2001
RE: assignable mutators (S06/Lvalue subroutines)
> If a routine is rw, you may optionally define a single "slurpy scalar" > (e.g., '*$value') in its signature. A good start, but why limit the Lvalue to a scalar? A list l-value seems like a pretty useful thing to me. -Martin --- Have you seen our website? http://www.vodafone.co.nz Manage Your Account, check your Vodafone Mail and send web2TXT online: http://www.vodafone.co.nz/myvodafone CAUTION: This correspondence is confidential and intended for the named recipient(s) only. If you are not the named recipient and receive this correspondence in error, you must not copy, distribute or take any action in reliance on it and you should delete it from your system and notify the sender immediately. Thank you. Unless otherwise stated, any views or opinions expressed are solely those of the author and do not represent those of Vodafone New Zealand Limited. Vodafone New Zealand Limited 20 Viaduct Harbour Avenue, Private Bag 92161, Auckland 1030 Telephone + 64 9 355 2000 Facsimile + 64 9 355 2001
RE: Split with negative limits, and other weirdnesses
Hmmm, my understanding was that it stopped *splitting* after the limit, but it doesn't stop "consuming" the source; rather the entire remainder is returned as the last item in the list, even if it contains the delimiter. A bit like this: sub split($pat, $src, $limit) { @r = split($pat, $src); return @r[0..$limit-2], join($pat, @r[$limit-1..*]); } except of course it works where $pat isn't a string literal, and does sensible things if $limit is 0 or 1, and is implemented more efficiently. -Martin > -Original Message- > From: Mark J. Reed [mailto:[EMAIL PROTECTED] > Sent: Monday, September 29, 2008 8:44 AM > To: Chris Davaz > Cc: Carl Mäsak; Perl6 > Subject: Re: Split with negative limits, and other weirdnesses > > On Sun, Sep 28, 2008 at 11:40 AM, Chris Davaz > <[EMAIL PROTECTED]> wrote: > > Ok, so 0 returns the empty list and -1 violates the > signature? In PIR > > can we have such signatures that put a constraint on the range of > > values for a given parameter? > > Maybe this has already been proposed and rejected, but why not simply > define the limit parameter such that > > split($pat, $src, $limit) > > is equivalent, result-wise, to > > split($pat, $src)[0 .. $limit - 1] > > ? Of course, the limit-parameter case might be able to avoid some > work compared to the second, which might not always be able to do its > job lazily, but the return value would be the same. Then you don't > have to come up with separate edge case rules for two different > constructs... the one follows logically from the other. > > $limit is 0? @foo[0..-1] is the empty list. Check. > > @foo[0..-2] is also the empty list. So negative parameters > don't need to Fail.. > > -- > Mark J. Reed <[EMAIL PROTECTED]> > --- Have you seen our website? http://www.vodafone.co.nz Manage Your Account, check your Vodafone Mail and send web2TXT online: http://www.vodafone.co.nz/myvodafone CAUTION: This correspondence is confidential and intended for the named recipient(s) only. If you are not the named recipient and receive this correspondence in error, you must not copy, distribute or take any action in reliance on it and you should delete it from your system and notify the sender immediately. Thank you. Unless otherwise stated, any views or opinions expressed are solely those of the author and do not represent those of Vodafone New Zealand Limited. Vodafone New Zealand Limited 20 Viaduct Harbour Avenue, Private Bag 92161, Auckland 1030 Telephone + 64 9 355 2000 Facsimile + 64 9 355 2001