Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • May 27 09:13
    evhub closed #663
  • May 27 09:13
    evhub labeled #663
  • May 27 08:55
    evhub opened #664
  • May 27 08:55
    evhub milestoned #664
  • May 27 08:55
    evhub labeled #664
  • May 27 07:14
    evhub labeled #663
  • May 27 07:14
    evhub milestoned #663
  • May 27 07:14
    evhub opened #663
  • May 27 06:33
    evhub demilestoned #662
  • May 27 03:59
    evhub milestoned #662
  • May 27 03:59
    evhub opened #662
  • May 27 03:59
    evhub labeled #662
  • May 25 22:07
    evhub labeled #661
  • May 25 22:07
    evhub labeled #660
  • May 25 22:04
    JacobFV opened #661
  • May 25 21:54
    JacobFV edited #660
  • May 25 21:48
    JacobFV opened #660
  • May 12 23:21
    evhub labeled #659
  • May 12 23:11
    JacobFV opened #659
  • Apr 23 21:14
    evhub closed #658
Thurston Sexton
@tbsexton
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
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
Thurston Sexton
@tbsexton
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.
like a DFS where we just return the leaves
we may not need the |> list part, rather leaving as a generator. the whole "stack" of generators would get flattened into one generator over the leaves
Evan Hubinger
@evhub
No, I don't think so—the function as I wrote it shouldn't flatten anything, and without list I don't think it does anything.
Evan Hubinger
@evhub
Here's a more general function that might help showcase what eval_iters is doing:
def recursive_map(func, () :: it) =
    it |> map$(recursive_map$(func)) |> func

addpattern def recursive_map(func, x) = func(x)

def list_it(() :: it) = list(it)
addpattern def list_it(x) = x

eval_iters = recursive_map$(list_it)

(|1, (|2, 3|), 4, (|5, 6|)|) |> eval_iters |> print
Henning
@henningsway
I use VScode (Insiders) with the new native Notebook API for interactive Python Scripting. As a former R user the functional possibilities of coconut appeal to me, but I have trouble selecting a coconut-kernel in vscode so far. It does work great for Jupyter in the Browser, though. Is there a chance to get this to work in vscode as well? :)
Evan Hubinger
@evhub
@henningsway Theoretically, VSCode supports TextMate syntax highlighting, which already exists for Coconut here—though I don't know how to get VSCode to use that file (I don't use VSCode myself). If you figure it out, I'd appreciate it if you could create a package or at least put the instructions here and I'll add them to the documentation.
kobarity
@kobarity
@evhub, I just published a VSCode extension kobarity.coconut based on your Coconut.tmLanguage. Thanks for your great work.
Actually, another extension based on the older version of Coconut.tmLanguage already exists, but it seems not maintained.
My new extension supports syntax highlighting on Coconut files and in Coconut code block in Markdown.
kobarity
@kobarity
vscode-insiders-coconut-jupyter.png
@henningsway, I tried VSCode Insiders and could select Coconut kernel. First I installed the extensions Jupyter, Python and Coconut. Then I connected to a remote Jupyter server, and selected the Coconut kernel.
Evan Hubinger
@evhub
Thanks @kobarity! I'll add that to the documentation.
Uroš Nedić
@urosn
Does Coconut support typeclasses?
Does Coconut suppory Unicode function names (combined with infix notation we can do very modern things)?
Evan Hubinger
@evhub
@urosn For typeclass-like syntax, you can use addpattern to match a different function depending on the input type, e.g.
match def to_json(x is str) = repr(x)
addpattern def to_json(x is int) = str(x)
addpattern def to_json(x is list) = x |> map$(to_json) |> list |> str
For unicode function names, Coconut supports PEP 3131 if given --target 3 (or above) and also supports a host of unicode alternatives to built-in operators.
Evan Hubinger
@evhub
Currently, as per PEP 3131, non-alphanumeric variable names are disallowed, though Coconut could theoretically add support for them if there's a compelling use case—feel free to raise an issue for that if you want it.
Also, for typeclasses, you can always just use typeclasses or something, though addpattern is probably going to be better than any library like that if you're working in Coconut.
fakuivan
@fakuivan
Hello
I'm using coconut as a replacement for the python kernel on jupyter
It's been great so far
There were some issues with the specs in kernel.json though, I installed coconut with pip3.9, but the argv array only refered to "python" and not "python3.9" or to the full path
Also, is there an analogue to toolz's valmap function?
fakuivan
@fakuivan
image.png
coconut is great, thanks for making this c:
Evan Hubinger
@evhub
@fakuivan If you run coconut --jupyter, it should automatically install a coconut kernel for the version that you run that command under. As for valmap, you can use fmap:
def valmap(val_func, input_dict) = input_dict |> fmap$((k, v) -> (k, val_func(v)))
fakuivan
@fakuivan
Wait
Does fmap know to destructure (the key, value) tuple?
the (key, value)*
Evan Hubinger
@evhub
yep! that's how fmap works on abc.Mapping objects.
servadestroya
@servadestroya
Hello
Is it possible to define fmap on new types?
Like addpattern fmap(f, obj is MyClass) = obj.map(f)
oh I see
the fmap dunder
it would be nice to have fmap be a pattern matched function so that this functionality could be added to third party libraries
Evan Hubinger
@evhub
@servadestroya __fmap__ is the way to do it, yep. If you want to add fmap support to a third-party object, you can always monkey-patch in an __fmap__ with
def ThirdPartyObject.__fmap__(self, func) = ...