## Where communities thrive

• Join over 1.5M+ people
• Join over 100K+ communities
• Free without limits
##### Activity
• Aug 15 20:34
evhub labeled #668
• Aug 14 15:15
JakartaLaw opened #668
• Aug 12 18:27
evhub closed #667
• Aug 12 18:27
evhub labeled #667
• Aug 12 09:37
tom-a-horrocks commented #667
• Aug 12 08:29
evhub commented #667
• Aug 12 08:29
evhub commented #667
• Aug 12 08:09
evhub commented #667
• Aug 12 07:59
evhub milestoned #667
• Aug 12 07:59
evhub labeled #667
• Aug 12 04:23
tom-a-horrocks edited #667
• Aug 12 04:22
tom-a-horrocks opened #667
• Jul 18 19:21
evhub labeled #666
• Jul 18 19:21
evhub closed #666
• Jul 18 19:21
evhub commented #666
• Jul 18 19:20
evhub labeled #666
• Jul 18 19:20
evhub edited #666
• Jul 15 13:28
timgates42 opened #666
• Jul 05 00:31
evhub labeled #665
• Jul 04 12:07
geezmolycos opened #665
Bruce Eckel
@BruceEckel

reduce(function, iterable[, initializer])

product = reduce$(*) range(1, 10) |> product |> print In this case, the second argument, iterable, is supplied by range(1,10). How would I add an initializer into this example? thanks. Evan Hubinger @evhub @BruceEckel You can do: range(1, 10) |> reduce$((*), ?, initializer) |> print
OldIronHorse
@OldIronHorse
Hi. I'm working my way through the classic "99 Problems" as I get to grips with Coconut and I've run into what looks like an inconsistency with the lazy iterator slicing. In order to make my implementation of "split" work I have to wrap the iterator with "reiterable" but a very similar looking implementation of "rotate" works just fine without it.
Here's the code:
def split(n, ls) =
ls = reiterable(ls)
(ls$[:n], ls$[n:])
def rotate(n, ls) = ls$[n:] :: ls$[:n]
OldIronHorse
@OldIronHorse
So I'm wondering what I've misunderstood here.
OldIronHorse
@OldIronHorse
Well, this is embarrassing: my test case for "rotate" wasn't passing a lazy list.
Now that it is the reiterable wrapper is required and consistency is restored.
Evan Hubinger
@evhub
@OldIronHorse Yep, that's right—reiterable is required when working with iterators (e.g. lazy lists), but not when working with iterables (e.g. lists or tuples).
Michael Tingley
@michaeltingley

Hi there! I'm new to Coconut (amazing project, by the way!!), and I was wondering if there's a way to enable --mypy type checking in a Jupyter kernel. I tried starting the kernel with python -m coconut.icoconut --mypy, but this gives me an error saying basically that --mypy is not a valid argument. I'm wondering if there's a way to forward along --mypy to the underlying Coconut runtime?

Or alternatively (more jankily), is there a way to enable mypy (e.g. some magic constant I can set to True) within the already-running Coconut runtime in order to have it enable mypy type checking?

Thank you!

Evan Hubinger
@evhub

@michaeltingley There's currently no way to do this using the Coconut Jupyter kernel, but you can do it with the Coconut Jupyter magic if you do %load_ext coconut and then:

%%coconut --mypy
x: str = 1

which should give you an error. Also, I should note that calling coconut.icoconut directly is generally not what you want to be doing; you should probably default to coconut --jupyter console or coconut --jupyter notebook instead.

Michael Tingley
@michaeltingley
This is very cool! Unfortunately, I can't get it to work. I'm getting the error variable names cannot start with reserved prefix _coconut. Here's a screenshot. Let me know if you have any ideas!

(There are also a few other warnings, which you can see in that image:

CoconutSyntaxWarning: unnecessary from __future__ import (Coconut does these automatically) (line 3)
from __future__ import print_function, absolute_import, unicode_literals, division
CoconutSyntaxError: variable names cannot start with reserved prefix _coconut (line 4)
  import sys as _coconut_sys
^
File "<string>", line unknown
import sys as _coconut_sys

)

Evan Hubinger
@evhub
@michaeltingley Ah, the problem is you're using %%coconut from inside a Coconut kernel, which doesn't work since Coconut ends up trying to compile that code twice, once by %%coconut and once by the kernel itself. You should try using %%coconut inside of a Python kernel instead.
Michael Tingley
@michaeltingley
@evhub Oh, OK, thanks. So there's no way to get mypy enforcement inside a Coconut kernel I guess? Thanks anyways for the help :)
Evan Hubinger
@evhub
@michaeltingley Not currently, but there's no fundamental technical obstacle to it. Feel free to raise an issue for it.
Actually, one other thing you could do is just use something like mypy-ipython, which should work inside of a Coconut kernel, since Coconut's kernel supports magics/extensions (though I haven't tested mypy-ipython myself).
Mihai Eugen Miuta
@miutamihai
Hi everyone! I just started out using coconut and I absolutely love it (especially the lambda function syntax change). Speaking of lambdas, I was wondering whether there's a way of using the addpattern syntax with lambda expressions. That would absolutely seal the deal for me :smile:
Evan Hubinger
@evhub

@miutamihai Statement lambdas certainly offer support for pattern-matching syntax—for example:

xs |> map$(def ({"a": a}) -> a + 1) And in terms of using addpattern, it's just a function, so you can certainly do something like: def ignore_zero(x, 0) = float("nan") safediv = addpattern(ignore_zero)(def (x, y) -> x / y) Thurston Sexton @tbsexton @evhub how would you like #513 to be addressed in practice? IMO we typically see something that looks like coconut-language-server as its own separate repo. Do you want to make a base repo with the dev-ops stuff you prefer, for us to PR to it? I've been researching how to implement an LSP with pylgs: https://github.com/openlawlibrary/pygls Thurston Sexton @tbsexton (unrelated: think I could do a quick PR to add this to your conf.py? the sidebar never scrolls unless I get waaaay down in the docs... just a minor pet peeve ^_^ https://github.com/ryan-roemer/sphinx-bootstrap-theme/issues/136#issuecomment-186860368) Evan Hubinger @evhub @tbsexton Separate repo seems good and if you want to just make it that seems good to me. I don't anticipate being able to contribute a ton, but certainly if there's anything I can do on the Coconut side to make things easier I'd be happy to. Re doc sidebar scrolling, I just pushed evhub/coconut@2bd81da which bumps the version per the PR you linked; hopefully that fixes the issue. Thurston Sexton @tbsexton oh cool. You may need to add something like 'navbar_fixed_top': "false", to the html settings in sphinx, per the last comment on that issue Evan Hubinger @evhub @tbsexton Ah, thanks—pushed evhub/coconut@78bb495 Thurston Sexton @tbsexton Hmm that didn't do what I expected ^_^ now the sidebar is locked to the top of the page (which i guess is obvious in retrospect haha) ... so we can't navigate from within the docs somewhere Maybe the best "alternative" is the globaltoc_depth:3 option? It that does what I'm assuming, then the sidebar would just have less "stuff" in it. Apologies, i'm not super familiar with the options in this sphinx theme (more of a mkdocs-material user myself) Evan Hubinger @evhub Just reading the documentation, I don't think globaltoc_depth does what you want—it looks like it conrols the "Site" dropdown, not the navbar. Andrey Logunov @capissimo A code snippet resource is essential for this project, imho, like the one for F# (http://www.fssnip.net/). Or is there any already? Evan Hubinger @evhub @capissimo That does seem useful; closest to that currently would just be the tutorial, examples in the documentation, my repositories using Coconut, or just searching for Coconut code on GitHub. Thurston Sexton @tbsexton @evhub fyi searching on Github leads to a bunch of results from the "Cocaine" language x) On another note, this might be a bug: string matching inside dicts? {'q'+n:val} = {'q1':2} print(n) CoconutParseError: parsing failed (line 1) {'q'+n:val} = {'q1':2} File "<string>", line unknown SyntaxError: parsing failed {'q'+n:val} = {'q1':2} the equivalend in a list works: ['q'+n, val] = ['q1',2] print(n) >>> 1 but not in a set works in a tuple Thurston Sexton @tbsexton Seems to only be a problem when the compound pattern is in the key, since it works when I try string-matching in the value Actually, pattern-matching on the keys seems broken further, eg. using tuple destructuring in the key: {('q1',n): '1'+val} = {('q1',2):'12'} print(n) Thurston Sexton @tbsexton yknow what, I literally asked this in 2019 haha. You said: @tbsexton Dictionary keys in patterns currently have to be constants, unfortunately--there's no current syntax for looking up keys based on values, only for looking up values based on keys. Feel free to raise an issue for that, though. so that answers it. I can look for/add an issue Evan Hubinger @evhub Yup, that's a limitation of the pattern-matching system—and unfortunately it's a very tricky one to solve, since it leads to a combinatorial explosion of possible matches based on trying to figure out which key should match. Evan Hubinger @evhub (It's the same reason you can't do head + [2, 3] + last = [1, 2, 3, 4].) Thurston Sexton @tbsexton yeah that's a great point. Though I will say, my workaround was to use tuples which work fine. It was a bit of an edge-case, perhaps. This was data formed from an OpenAPI schema, so they had a lists of single-pair dicts. [{k1,v1},{k2:v2},...] etc. So I was pattern matching on only one key to dispatch to whatever function needed to be executed on the value for a given key. I knew the dicts were singletons, so it was ok to use match def f(d is dict) = f(d.items()|>list|>.[0]) and do all the logic in tuples I do have another question: what would the equivalent of yield from be in terms of maps? When using a nested lazy sequence, even calling list on the resulting generator usually returns a list of a bunch of lazy sequences (of possibly unknown depth). Is there a command/pattern for recursively consuming/yielding all generators? I know in the past I used for gen in super-gen: yield from gen, but alas, this inhibits my quest to be rid of for-loops ^_^ Thurston Sexton @tbsexton (p.s. this is a super common pattern in e.g. Pandas dataframe construction, where there might be a single generator you pass to the constructor that yields rows, but internally you want it to be defined with sub-generators. Obviously I'd prefer to build these with map/fmap as opposed to for ... yield from but i always seem to end up with a top-level list full of un-executed generator functions Thurston Sexton @tbsexton I did figure out a single-level version of this... top_gen |> (::) <*.. map$(nested_gen)
but this is not recursive... cannot exhaust all generators in the "stack".
Mostly just don't know what I'd call this, I'm imagining it's like a "flush" where every generator gets exhausted if it exists, returning their result (e.g. into a list).
Evan Hubinger
@evhub
@tbsexton Maybe try:
def eval_iters(() :: it) =
it |> map\$(eval_iters) |> list

addpattern def eval_iters(x) = x
Thurston Sexton
@tbsexton
@evhub huh actually when you write it out like that, this is just an iterator over a "tree" of iterators to grab all the leaves in order.