Code Monkey home page Code Monkey logo

6.d-prep's People

Contributors

jnthn avatar lizmat avatar molecules avatar samcv avatar skarsnik avatar tbrowder avatar zoffixznet avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Forkers

seanpm2001

6.d-prep's Issues

6.d Roast Commits In Need of Knowledgeable Review

Going to log here roast commits I spot during 6.d review that I've no idea if they're right or not:

  • Raku/roast@c435912 -- the test includes is repr('CUnion'). Is that stuff proper spec or just Rakudo-specific thing? I see only two other tests that make use of is repr trait, so it doesn't seem to be something that's properly specced.
  • R#2073 -- Bad propspec: Enum's :D accepts Enum's :U

Add a "clear" method to Array and Hash (@a.clear, %h.clear)

To clear/empty an array or hash, the value Empty should be assigned to it (or a call to the undefine() function should be made):

@a = Empty;
%h = Empty;

Is it possible to add a method to arrays and hashes that does exactly and just this, clear the container? I think it's a basic enough operation to deserve its own method. Example:

@a.clear
%h.clear

(It could be called any other name, I just think "clear" is a good one :-)

Comparing to other languages, at least these objects have a "clear" method: Java collections, Python lists and dictionaries, Ruby arrays and hashes, and JavaScript Map and Set objects.

If this suggestion is accepted, then the return value of the .clear method should be decided:

  • always returns self
  • always returns Empty (or Nil, or Any, or some other special value)
  • returns a list of the elements just removed, ie., the previous content of the container before emptying it.
  • returns the number of elements just removed (zero if it was already empty; the .elems of the container before the operation)

Should different values be returned indicating if there was any changes or not (ie. if the container was already empty or not) ? To be used in idioms like these:

if x.clear {
    say 'The container was emptied';
} else {
    say 'The container was already empty';
}

# Or:

given x.clear {
    when ... {...}
    when ... {...}
}

Do something about the undefine() function

The undefine routine is defined in file src/core/operators.pm as:

multi sub undefine(Mu    \x) is raw { x = Nil   }
multi sub undefine(Array \x) is raw { x = Empty }
multi sub undefine(Hash  \x) is raw { x = Empty }

It seems to be reminiscent from Perl 5, where you can write like this:

undef $x;  # sets $x to undef
undef @a;  # clear array content
undef %h;  # clear hash content

But whereas in Perl 5 it makes sense, I fail to see the purpose of it in Perl 6. If the programmer wants to clear a container (or set it to its default value), they can just assign Nil or Empty themselves:

$x = Nil;
@a = Empty;
%h = Empty;

If it's for the convenience of having a function that does just this, then shouldn't it have a more appropriate name? "reset"? "clear"? "set-to-default"? "undefine" besides being a longer name than "undef", doesn't do what its name says, it doesn't undefine variables in the ".defined method" meaning:

my $x is default(42);
my @a;
my %h;

undefine $x;
undefine @a;
undefine %h;

say $x.defined;  #=> True
say @a.defined;  #=> True
say %h.defined;  #=> True

It feels strange in this situation:

> my $a is default(42); $a = 10; dd $a; undefine $a; dd $a
Int $a = 10
Int $a = 42

> my $a is default(42); $a = []; dd $a; undefine $a; dd $a
Array $a = $[]
Slip $a = Empty

So, is there any plans for what to do with the undefine function? Or this should stay as it is?

Implement `replace`, deprecate `subst` in favor of `replace`

This should be moved to FEATURES.md, but I'll write it here for now. Maybe we'll even decide against it?

See this: rakudo/rakudo#1314 (comment)

I don't know about others, but I constantly mistype or misexpand subst/substr. The two names are just too similar. I think the suggestion to rename subst as replace makes sense. In v6.d, we can start to give deprecation warnings for subst, suggesting to switch to replace. And we can get rid of subst completely in v6.e.

Should we make `$_` no longer be `is dynamic` in 6.d (plus provide mitigation for where it needs to be)?

Background

All of $/, $!, and $_ default to is dynamic. This means that they can be accessed through CALLER:: and similar introspection features. For $/, this is used heavily to set $/ from various bits of the regex matching mechanism. For $!, I'm not aware of any current usages. For $_, the only usage I'm aware of so far is in the various P5 compatibility modules, which use CALLER::<$_> in order to emulate the "works on $_ by default" semantics of the Perl 5 built-ins.

Performance considerations

Consider for ^10_000_000 { }. This works by invoking the block with the current value, thus populating its $_. In this case, the loop is optimized such that the iteration counter is done with native values, the boxing taking place in the parameter handling of the block.

Ideally, we'd be able to see that the boxing is not required and eliminate it. Since boxing is a memory allocation of an object that then needs to be GC'd, that is potentially significant. Of course, we don't really care about it for the purpose of an empty loop body, which no real program would ever contain. But what if the loop does contain something? Can we be sure that it won't ever do CALLERS::<$_>?

The immediate answer is, "as soon as we have late binding, then no". That means "as soon as we have a method call", for example. One might wonder if we can't just let inlining take care of matters: if the loop is hot enough, we will hopefully inline all of the things anyway, and then we can see what the code does. While that can indeed happen, it's not so simple. We do a lot of speculative optimization, with guard clauses triggering deoptimization. Just because our optimized code can never take a path where CALLERS::<$_> is used doesn't mean that it won't deopt and then find itself on a place where it is used.

Another good question is, "but can't the upcoming work on partial escape analysis save us", and the answer is "yes, but..." We could:

  • Use normal local registers to model the lexical store
  • Flush them to the real lexical store at the point we either make a non-inlined call or perform deopt, since that's where they may escape

This would work great for our microbenchmark here, and others where we manage to fully inline everything, or at least where the non-inlined path is taken rarely, so the $_ only sometimes escapes. But for for ^10_000_000 { $obj.some-very-big-method } or similar, we'd not be able to do much apart from assume the worst.

I've picked the for case as a concrete example, but $_ usage is incredibly widespread in idiomatic code:

  • given $foo { }
  • with $bar { }
  • .map({ .foo + .bar })

And in all those we'll run into the same optimization challenges.

For $/ and $!, I'm not that concerned: the former would be swallowed up by the cost of regex handling anyway, and the latter only shows up in exceptional cases, which by definition are rarely taken.

How much does this matter?

I believe the bar should be set pretty high for "we should change the language because X is hard to optimize". There's many things in Perl 6 that are challenging to make run fast, but we're making good progress on that anyway. To put this in to perspective, the current situation is that given these:

# Perl 6
for 1..10_000_000 {
}
# Perl 5
for (1..10_000_000) {
}
# Python
for x in range(0, 10000000):
    pass
# Ruby
for i in 1..10_000_000
end

Then currently, measured on my none-too-fast home VM and using the experimental postrelease-opts version of MoarVM, we get:

  • Perl 6: 0.484s
  • Perl 5: 0.247s (so 1.95x faster than Rakudo)
  • Python: 0.565s (so Rakudo is 1.17x faster Python)
  • Ruby: 0.419s (so Ruby is 1.15x faster than Rakudo)

If we were to normalize for startup time, we'd be beating Ruby and within 1.3x of Perl 5 (but I don't really think we should be hiding our startup time, but rather improving it :)). But then consider:

my int $i = 1; while $i++ <= 10_000_000 { }

Which runs in 0.261s. We should be able to optimize the range case in to this, and granted, with sufficiently smart PEA we'll be able to. But as noted, microbenchmarks are not representative of real programs, where "inline everything" isn't really realistic.

Usage of $_ as a dynamic

I'm only currently aware of use of $_ being dynamic by the Perl 5 compatibility modules. I'm partly writing this to solicit input from those who may be aware of other cases that I have failed to consider. If that really is the only use of this feature, we might want to consider picking a more optimizable and analyzable default scope for $_ (e.g. "normal lexical").

Mitigation for modules relying on $_ as dynamic

I'd propose in 6.d

  • A pragma, use dynamic <$_> or similar, for indicating that we want $_ to get dynamic scope
  • A means to export pragmas to the user of the module (perhaps an EXPORTPRAGMA to go with EXPORTHOW or some such), so that the P5 compat modules can do that and require their users to do nothing different than they do today

Further benefits

  • The programmer can consider $_ the same way they consider their other lexicals: if you can't textually see it being changed and you aren't passing it somewhere, it won't be being changed
  • Other analysis tools can do that same (in the absence of the pragma)
  • We'd get a general pragma export mechanism out of it

Drawbacks

  • It breaks the consistency that "all the magic variables are is dynamic"
  • The new pragma and export mechanism would need implementing, tests, docs, etc. (I'd be willing to do that, but it's more that it's an ongoing cost, like everything we add)
  • It feels like a small defeat to propose a language change rather than just getting cleverer at building an optimizer :-)

Change the default value of native num variables from NaN to 0e0

While native int variables are initialized with 0:

> say my int $
0

Native num variables are initialized with NaN:

> say my num $
NaN

Is it possible to change the default value of native num variables to 0e0?

This way, it would match the value returned by Num.new:

> say Num.new.perl
0e0

(As an argument, the C standard requires that static numeric variables be initialized to 0.)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.