Skip to content

Conversation

Nycto
Copy link
Contributor

@Nycto Nycto commented Apr 5, 2025

This changes adds more procs to the options stdlib. These are convenience functions that make life easier when interacting with Options -- I've wound up adding them to just about every app I have written with Nim.

@Nycto Nycto force-pushed the options branch 2 times, most recently from eca83a3 to ee24d96 Compare April 7, 2025 15:10
@Nycto
Copy link
Contributor Author

Nycto commented May 3, 2025

The failure being reported in CI is:

 tests/stdlib/thttpclient_ssl.nim c

Failure: reExitcodesDiffer
Expected:
exitcode: 0

Gotten:
exitcode: 1

Output:

[Suite] SSL self signed certificate check
    [1746287859.487293] server: ready
    [1746287859.5890162] client: connect
    [1746287859.5897272] server: incoming connection
    [1746287859.5898144] server: accepting connection
C0F6BF7BB47F0000:error:0A000418:SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca:../ssl/record/rec_layer_s3.c:1599:SSL alert number 48
    [1746287859.6046548] server: receiving a line
    [1746287859.705398] client: connect
    [1746287859.7056324] client: unexpected exception: Connection refused
  [FAILED] HttpClient default: no check
    [1746287859.811127] server: ready
    [1746287859.9555795] server: ready
    [1746287859.9844153] client: connect
    [1746287859.9847176] server: incoming connection
    [1746287859.9848032] server: accepting connection
    [1746287859.9955516] client: exception: error:0A000086:SSL routines::certificate verify failed
C0F63F7BB47F0000:error:0A000418:SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca:../ssl/record/rec_layer_s3.c:1599:SSL alert number 48
    [1746287859.9997697] server: receiving a line
    [1746287859.9997885] server: received 0 bytes
    [1746287859.999796] closing
    [1746287859.99985] server: exited
    [1746287860.1011178] client: connect
    [1746287860.1013148] client: exception: Connection refused
    [1746287860.1013272] getContent should not have raised an exception
  [FAILED] HttpClient with CVerifyPeerUseEnvVars

I may be missing something, but that seems unrelated to the change in this PR

@Araq
Copy link
Member

Araq commented May 4, 2025

I may be missing something, but that seems unrelated to the change in this PR

Correct, don't worry.

@arnetheduck
Copy link
Contributor

for results, I've been planning to reuse tricks like https://github.com/nim-lang/Nim/blob/version-2-2/lib/pure/collections/sequtils.nim#L97 to avoid most of the extra copies that are unnecessary - this implementation is very heavy on copies in general, often in a way that is tricky for the compiler to get rid of.

a second trick to use is to verify that the code efficiently moves data around and/or uses cursors where applicable, ie in Option[string], withValue should not copy the string inside the some case when it already has a stack copy of the Option instance, or this implementation will defeat one of the main purposes of using it, namely to work with values without said overhead. Imagine using it with a 10mb string.

@arnetheduck
Copy link
Contributor

In particular, see https://github.com/arnetheduck/nim-results/blob/df8113dda4c2d74d460a8fa98252b0b771bf1f27/results.nim#L1430 for a much more efficient way to inject a variable into a template - there is also a variation on the same theme when genericsopensym is not enabled.

@Nycto
Copy link
Contributor Author

Nycto commented Jul 12, 2025

Sorry for the delayed update. Rebased and pushed a new version that should prevent copies. CI failures look unrelated to my changes.

Note that I removed the ‘valueOr’ template as I couldn’t figure out how to implement it without requiring a copy. I didn’t want to block the other changes on that one snag, though

outcome = action
outcome

template filterIt*[T](value: Option[T], action: untyped): Option[T] =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better rename the action to pred for consistency with other filter templates in stdlib

Comment on lines +473 to +480
block:
var outcome = value
outcome.withValue(it):
if not action:
outcome = none(T)
do:
outcome = none(T)
outcome
Copy link
Contributor

@ZoomRmc ZoomRmc Sep 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just?

Suggested change
block:
var outcome = value
outcome.withValue(it):
if not action:
outcome = none(T)
do:
outcome = none(T)
outcome
block:
evalOnceAs(local, value)
template it(): auto {.inject, used.} = unsafeGet(local)
if local.isSome and action:
value
else:
none(T)

You can't simply use withValue here as an expression with the current implementation, unfortunately. This might be worth looking into.

outcome

template applyIt*[T](value: Option[T], action: untyped) =
## Executes a code block if the `Option` is `some`, assigning the value to a variable named `it`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To follow the common apply semantics this should work:

var o = "foo"
echo o.applyIt(it = "bar")

Then the docs should clearly draw attention to mapIt being able to return another type and applyIt just working on the held value of the same type.

Apply should return the same type being passed to it, but this just does whatever (or doesn't?). To think more about it, Option is not exactly a container, this template looks confusing applied to it and redundant.

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

Successfully merging this pull request may close these issues.

4 participants