This compiles:
proc foo: seq[int] =
return lc[x | (x <- 1..10, x mod 2 == 0), int]
This doesn't
proc foo[T]: seq[int] =
return lc[x | (x <- 1..10, x mod 2 == 0), int]
Error: undeclared identifier: '|'
This is stdlib problem, the language works as expected here. The following compiles:
import future
proc foo[T]: seq[int] =
mixin `|`, x, `<-`
return lc[x | (x <- 1..10, x mod 2 == 0), int]
The lc macro needs to be redesigned.
Not sure if my comment is out of place, but I encourage fixing this. I was trying to write an iterator over combinations (like the one in Python's itertools module) and I encountered this problem. It would be nice if I were able to use lc with generics in this case.
In addition to this: IMO, and I think @Araq agrees, the list comprehensions should be made more Pythonic.
I think in the long run we want to obsolete this macro and allow a for loop as an expression.
High priority because we need to make a decision (if we decide to remove then this will be a breaking change)
I don't understand the difference between the following two cases:
This one doesn't compile:
proc dist(bc1, bc2: string): int {.inline.} =
mixin `|`, `<-` # Error: invalid expression: 'mixin `|`, `<-`'
sum(lc[int(pair.a != pair.b) | (pair <- zip(bc1, bc2))])
This one does:
proc matchToAllowed(fastq: Fastq): (string, string) =
let bcSeq = fastq[1][(bcStart-1)..<(bcStart + bcLen - 1)]
let bcQuals = fastq[2][(bcStart-1)..<(bcStart + bcLen - 1)]
let bcProbs = nucProbs(bcSeq, bcQuals)
proc likelihood(barcode: string): float =
var letter: char
var errProb: float
result = 1
for i, np in bcProbs.pairs():
(letter, errProb) = np
if letter == barcode[i]:
result = result * (1 - errProb)
else:
result = result * (errProb / 3)
mixin `|`, `<-` # No problem here
let likelihoods = lc[likelihood(allowed) | (allowed <- barcodes), float]
var maxLike = likelihoods[0]
var bestIdx = 0
# https://stackoverflow.com/a/48123056/1878788
for idx, like in likelihoods:
if like > maxLike:
maxLike = like
bestIdx = idx
let candidate = barcodes[bestIdx]
let theDist = dist(bcSeq, candidate)
let annot = join([
candidate,
formatFloat(maxLike, ffScientific),
theDist.intToStr], ":")
if theDist > maxDiff:
result = ("Undetermined", annot)
else:
result = (candidate, annot)
I have import future in both cases.
mixin is only valid in a generic proc or a template.
@Araq It doesn't seem to me that my second example is generic, or is a template. Did I miss something?
Ran the code in the OP on current devel https://github.com/nim-lang/Nim/commit/91b37311d9974ae30745946a52c9a971da1616f4 and it works fine now.
Ran the code in the OP on current devel 91b3731 and it works fine now.
Can confirm for 0.19.
I think in the long run we want to obsolete this macro and allow a for loop as an expression.
We now have for-loop macros.
Can we close this one?
Can we close this one?
Requires a test case.
Most helpful comment
I think in the long run we want to obsolete this macro and allow a for loop as an expression.