Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • May 12 23:21
    evhub labeled #659
  • May 12 23:11
    JacobFV opened #659
  • Apr 23 21:14
    evhub closed #658
  • Apr 23 21:14
    evhub commented #658
  • Apr 23 21:13
    evhub labeled #658
  • Apr 23 21:13
    evhub milestoned #658
  • Apr 23 21:13
    evhub labeled #658
  • Apr 23 21:13
    evhub opened #658
  • Apr 22 20:29
    evhub commented #657
  • Apr 22 20:29
    evhub closed #657
  • Apr 22 20:29
    evhub commented #657
  • Apr 22 20:26
    evhub milestoned #657
  • Apr 22 20:26
    evhub labeled #657
  • Apr 22 20:25
    evhub labeled #657
  • Apr 18 16:47
    tbsexton opened #657
  • Mar 29 21:36
    evhub demilestoned #654
  • Mar 28 07:48
    evhub closed #656
  • Mar 28 07:48
    evhub commented #656
  • Mar 28 07:45
    evhub labeled #656
  • Mar 28 05:12
    Sitwon commented #656
vip-ehowlett
@vip-ehowlett

We could for sure use a lot of the Python language server, however, on top of what you said, I also see an issue with code completion/type inferencing when using the superset.

As for the implementation of disc. unions, that'd be a little clunky. Trying to think of something that'd run in all versions, we'd compile a class with an array of the field names and then when we match, we'd essentially just be matching on values in that array for which we can return self.field. I'm pretty sure type inferencing on that would be out the window, though.

Evan Hubinger
@evhub

@vip-ehowlett What would that discrete union implementation give you that something like

data Empty()
data Leaf(n)
data Node(l, r)

Tree = (Empty, Leaf, Node)

def size(Tree()) = 0
def size(Tree(_)) = 1
def size(Tree(_, _)) = 2

doesn't give you?

vip-ehowlett
@vip-ehowlett
You have to know the structure of the tuple with this. I"m not sure how often the case would be, but with the other implementation, you can just match on the name of the tag.
Evan Hubinger
@evhub

@vip-ehowlett Coconut can also do

Tree = (Empty, Leaf, Node)

def size(t is Tree) = 1 + sum(map(size, t))

where you don't have to know the structure of the tuple, if that would solve your use case.

vip-ehowlett
@vip-ehowlett

It might.

I usually use discriminated unions to wrap possible function arguments. Below is what I was hoping for.

possible_args = ( option1: str, option2: int, option3: MyCustomDeeplyNestedObject )

def my_function( args : possible_args ) :
     match args:
         case str instance_variable: exprs / stmnts on strings
         case int instance_variable: exprs / stmnts on ints
         case MyCustomDeeplyNestedObject instance_variable: exprs / stmnts on MyCustomDeeplyNestedObject

But I'm not sure if I can use is in that match statement. That would be checking to make sure the variable refers to the same object reference, right?

Evan Hubinger
@evhub

@vip-ehowlett is in pattern-matching just does type-checking, not check that it's the same object reference. Here are some ways you could write your example in Coconut:

def my_function(x is str) = exprs/stmts on strings
addpattern def my_function(x is int) = exprs/stmts on ints
addpattern def my_function(x is MyCustomDeeplyNestedObject) = exprs/stmts on MyCustomDeeplyNestedObjects

or

def my_function(arg):
    case arg:
        match _ is str: exprs/stmts on strings
        match _ is int: exprs/stmts on ints
        match _ is MyCustomDeeplyNestedObject: exprs/stmts on MyCustomDeeplyNestedObjects

or

possible_args = (str, int, MyCustomDeeplyNestedObject)

def my_function(arg is possible_args):
    case arg:
        match _ is str: exprs/stmts on strings
        match _ is int: exprs/stmts on ints
        match _ is MyCustomDeeplyNestedObject: exprs/stmts on MyCustomDeeplyNestedObjects
Evan Hubinger
@evhub

If you're using coconut-develop (or in the next released Coconut version), you'll also be able to do

def my_function(arg):
    match arg:
        case class str(): exprs/stmts on strings
        case class int(): exprs/stmts on ints
        case class MyCustomDeeplyNestedObject(): exprs/stmts on MyCustomDeeplyNestedObjects

if you prefer that syntax, which is making use of Coconut's implementation of PEP 622, which is fully supported in develop now and will come out in the next release.

dontmindmehere
@dontmindmehere
hello
I'm just learning coconut
thought I understood the syntax pretty ok but can't get this to work on the coconut-lang.org repl:
num = next(filter(lambda i: i<3, nums), 0)
num = nums |> filter$((i -> i<3), ?) |> next$(?, 0)
Evan Hubinger
@evhub

@dontmindmehere When I use the website interpreter to run

nums = count()
num = next(filter(lambda i: i<3, nums), 0)
print(num)
num = nums |> filter$((i -> i<3), ?) |> next$(?, 0)
print(num)

I get

0
0

which seems right to me. What error are you seeing instead? Also, though this should work with the website interpreter, I think it is running a relatively outdated version of Coconut, so it won't have all the new features (though it should support everything you're using there).

dontmindmehere
@dontmindmehere
oh
it was the newlines
I had written it like this
num = nums
    |> filter$((i -> i<3), ?)
    |> next$(?, 0)
works when I escape newlines
dontmindmehere
@dontmindmehere
thanks
I started learning Rust and now I'm missing the functional stuff in python xd
Evan Hubinger
@evhub
@dontmindmehere Ah, yes. Coconut handles whitespace just like Python, which means you can escape newlines with backslashes, but the preferred way is just to use parentheses, as in
num = (nums
    |> filter$((i -> i<3), ?)
    |> next$(?, 0))
dontmindmehere
@dontmindmehere
oh nice, didn't know you could do that
Aaron Virshup
@avirshup

Hi - I was wondering if there's any way to reproduce the functionality of pip install -e for a project with coconut files in it.

My guess is that you'd need to set up a file watcher (e.g., watchdog) to handle recompiling files when they're changed? But was wondering whether there might be alternative strategies

Evan Hubinger
@evhub
@avirshup Like you were saying, you could use coconut --watch—but better might be to use automatic compilation. If you make sure in the root of your project (e.g. the top-level __init__.coco) you import coconut.convenience then compile fully once, pip install -e should do what you want. Also, if you're using coconut-develop (which you can get via pip install -U coconut-develop), you can run coconut --site-install which will make coconut.convenience imported automatically on Python start so you don't have to import it in the project root.
Aaron Virshup
@avirshup
@evhub - Ah, apologies - I completely missed that in the documentation. That looks excellent, I'll try it out. Thanks!!!
Peter Henry
@mosbasik

Just heard of this via the recent HN thread; started going through the interactive tutorial. The pattern matching "now you try it" page (https://hmcfabfive.github.io/coconut-tutorial/Patternmatch/Patternmatch_p3.html) is a little rough around the edges, imo. I get that its purpose is to teach pattern matching syntax, but the solution makes a lot of choices the motivations behind which I don't understand.

fwiw, my solution was

from collections import Counter
items |> Counter |> print

(which btw I was pretty tickled to hit on, coconut makes that pretty darn clean :) )

  1. Why the choice to make itemsan iterator? Seems like it'd be fine to leave it as a list.
  2. Relatedly, later we could use a for loop instead of a whileloop and avoid manually defining a stop condition, manually calling next(), etc.
  3. Why mess around with a current variable inside the match branches? wouldn't an aluminums[0] += 1 work?
  4. I get that you need to pass mutable structure(s) into countItems() to accumulate results, which explains the single-element lists. One could use a single dict instead (arguably more Pythonic), but then of course you actually don't need the pattern matching at all because you just use the item string as the key and you only need to write a single case (which is how I hit on using Counter in the end).

I was surprised enough at these choices that I was expecting another page saying things like "we prefer to use iterators in coconut because...", but that was the end of the pattern matching section. So I was considering thinking for a little bit to come up with a toy problem that really demonstrates how pattern matching can improve on vanilla python's approach - but I hesitated because I haven't gone through the whole tutorial yet and wanted to make sure I wasn't being totally oblivious to something.

Peter Henry
@mosbasik
(some minutes later) naturally, of course, the tutorial continued to expand on pattern matching and showed off some meatier uses for it - so my point 4 is maybe moot.
Evan Hubinger
@evhub
@mosbasik The real answer is that the interactive tutorial was written by a group of non-core Coconut contributors (which is to say, not me), so I can't really comment on the particular choices that it makes. The non-interactive tutorial was written by me, but it's also pretty old and obviously non-interactive. If you wanted to make some changes to the interactive tutorial, I'd be happy to pull them in and put them up.
Peter Henry
@mosbasik
cool, thanks for the response. I'll read with an eye to how I might improve things then.
Juan Castillo
@cfuendesign
image.png

Hey! I tried installing coconut through "pypy3 -mpip install coconut" and, despite the install looking like it went well, "coconut -h" isn't recognized as a command.

I'm an absolute beginner in both pypy3 and coconut, so feel free to correct me.

Juan Castillo
@cfuendesign
Ah, running coconut -h directly from pypy3's scripts folder did the trick.
image.png
Evan Hubinger
@evhub
@cfuendesign Yeah, you need to add the scripts folder to your PATH environment variable. See: https://datatofish.com/add-python-to-windows-path/
Alternatively, you can always just do pypy3 -m coconut -h.
Ivan Cheung
@ivanmkc

Beginner here!

Looking forward to using Coconut but am stumped by something simple.

I'm trying to unpack my parameters (key, value) passed into the map function:

{"A": 1, "B": 2, "C": 3}.items() |*> map$((key, value) -> value) |> list |> print

This works but is "uglier":

{"A": 1, "B": 2, "C": 3}.items() |> map$(key_value -> key_value[1]) |> list |> print
Expected output: [1, 2, 3]
Any help is appreciated :) I'm using Python 3 btw since I know tuple deconstruction changed at one point.
Ivan Cheung
@ivanmkc
Here's another version using a statement lambda, but also not quite as nice as I'd like:
(
{"A": 1, "B": 2, "C": 3}.items() 
    |> map$(def (key_value) -> key, value = key_value; value) 
    |> list 
    |> print
)
Ivan Cheung
@ivanmkc
I know this would work, but I actually want the parameters to be named and unpacked so I can reference either of them (even though I only use "value" in this example):
{"A": 1, "B": 2, "C": 3}.items() |> map$(-> _[1]) |> list |> print
Evan Hubinger
@evhub
@ivanmkc Here are some options that you might like:
d = {"A": 1, "B": 2, "C": 3}
d.items() |> starmap$((k, v) -> v) |> list |> print
d.items() |> map$(def ((k, v)) -> v) |> list |> print
d.items() |> map$(.[1]) |> list |> print
Ivan Cheung
@ivanmkc
Thanks! This is perfect.
Thurston Sexton
@tbsexton

@GianpieroCea Saw your question about data science.

I haven't seen any but I will say that, barring the lack of LSP that keeps me mostly using coconut for prototyping in the notebook, i use coconut constantly for data science. I love what it's done for the maintainability of my code, as well.

So with that, though I've avoided using coconut for codebases that require collaboration (since not many folks can write/read it right away), I would love to start a coconut-for-data-science tutorial.

Been learning/using jupyter book and that could be a great way to do something fast and pretty. let me know if you want to join a repo where we can plan out e.g. key contents and case studies, and I can help adding code based on my irl experience.

same goes for anyone else! :)
pigs
@pigs:riot.firechicken.net
[m]

I'm trying to setup coconut inside Databricks and came across a bug when trying to use the coconut magics:

TypeError: run_cell() missing 1 required positional argument: 'raw_cell
`

However, looking at the backtrace it is clear that the positional argument was given ipython.run_cell(compiled, shell_futures=False)

Evan Hubinger
@evhub
@pigs:riot.firechicken.net Strange. Can you raise an issue and include the traceback and ipykernel version (also anything else that might help me replicate it)?
Jason O.
@puruzio
I am trying coconut as the kernel_name for Papermill and it complains like this. Is there a way to fix this? coconut3 does show up in jupyter kernelspec list.
No parameter translator functions specified for kernel "coconut3' or language 'coconut'
Evan Hubinger
@evhub
@puruzio Should be fixed if you pip install -U coconut-develop (see #658).
Jason O.
@puruzio
Thank you, but the issue still persists for some reason. Same error message.
Evan Hubinger
@evhub
@puruzio Can you put exactly what you did and what versions you were on in the linked issue?
Jason O.
@puruzio
@evhub Sure. I uninstalled the Coconut 1.6 version, and installed coconut-dev 2.0 using the command you mentioned above.
Jason O.
@puruzio
@evhub Never mind. It's working! I accidentally installed coconut outside of venv.