Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot force order of operations #21

Open
arendsee opened this issue May 4, 2024 · 0 comments
Open

Cannot force order of operations #21

arendsee opened this issue May 4, 2024 · 0 comments
Assignees

Comments

@arendsee
Copy link
Collaborator

arendsee commented May 4, 2024

Suppose we have a sampleBy function that selects items from a list of pairs based on the second element value and then returns the selected first values. It takes a function of all the second values and returns their indices in the original list. This can be implemented as below:

sampleBy :: ([b] -> [Int]) -> [(a, b)] -> [a]
sampleBy f xs = map (at (map fst xs)) (f (map snd xs))

Where

-- lookup a value in a vector by index
at :: [a] -> Int -> a
fst :: (a, b) -> a
snd :: (a, b) -> b
map :: (a -> b) -> [a] -> [b]

The sampleBy implementation looks nice, however, when the code is generated, the map fst xs expression is re-evaluated at every index lookup. I want to force it to be evaluated only once. I can rewrite the expression as:

sampleBy f xs = map (at labels) (f (map snd xs)) where
  labels = map fst xs

But this evaluates to exactly the same code again, with labels being substituted into the main expression.

What would be nice is a means to force order of evaluation. Perhaps with let syntax?

sampleBy f xs =
  let labels = map fst xs
  let data = map snd xs
  map (at labels) (f data)

Where the compiler guarantees labels will be evaluated just once before the main expression. Adding let is a pretty major change.

Alternatively, we could define let as a source functions that forces evaluation:

let :: a -> (a -> b) -> b

This approach may serve as workaround until we implement real let handling.

@arendsee arendsee self-assigned this May 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant