2012-03-27 10 views
17

Qualcuno sa come ottenere la traduzione (solo parziale di Scala) di una espressione for/comprehension prima di tentare effettivamente di compilare il REPL (o il compilatore)?Ottenere la parte desugared di un'espressione di Scala/comprensione?

L'unica cosa che ho trovato finora è la bandiera del compilatore "-print", ma che ti dà la traduzione completa Scala ...

risposta

21

non sembra al esiste qualsiasi possibilità desugare espressioni "per/comprensione" direttamente all'interno della REPL. Ma come una alternativa è possibile utilizzare alcune opzioni del compilatore Scala come "-print" o per le espressioni semplici "Xprint: typer -e"

Esempio:

Per ottenere l'output desugard da un file utilizzare il "-print "bandiera:

# scala -print file.scala 

Per desugar una semplice espressione sola linea, usi "-Xprint: bandiera typer -e":

# scala -Xprint:typer -e "for (i <- 0 to 100) yield i" 
+2

Prima di tutto, dovresti usare '-Xprint: parser' per vedere solo il desugaring. Inoltre, puoi usare questo con il REPL come questo 'scala-Xprint: parser'. Tuttavia, rivelerà anche tutto il codice wrapper che il REPL mette attorno al tuo codice. – mgd

30

Come ho già detto in un altro topic, scalac -print stampe fuori codice Scala, non Giava. Traduce tutte le parole chiave di scala che non sono direttamente compatibili con Java al normale codice di scala. Non è possibile lasciare che il compilatore traduca solo parti afaik. Ma fondamentalmente una comprensione per sempre viene sempre tradotta allo stesso modo.

Un semplice per/rendimento simili

for(x <- List(1,2,3)) yield x*x 

sarà tradotto per

List(1,2,3).map {x => x*x} 

E senza resa

for(x <- List(1,2,3)) println(x) 

a

List(1,2,3).foreach{x => println(x)} 

fors annidati saranno tradotti a flatMap nidificato/carta costruisce

for(x <- List(1,2,3); y <- List(4,5,6)) yield x*y 

sarà tradotto al

List(1,2,3).flatMap { x => 
    List(4,5,6).map { y => 
    x*y 
    } 
} 

Quindi non c'è assolutamente nessuna magia

+6

Il mio male, hai assolutamente ragione! Ho anche trovato il flag del compilatore -e per espressioni semplici come: scala -Xprint: typer -e "val i = 1" – IODEV

+0

+1 Stavo cercando il codice desugared, non le flag. – ziggystar

14

Per vedere il risultato dopo l'uso semplice Dezuccheraggio il 01.230.324,028 milaopzione.

Se si dispone di questo semplice file di input denominato test.scala:

object Test { 
    for(x <- List(1,2,3); y <- List(4,5,6)) yield x*y 
} 

Poi compilarlo usando scalac -Xprint:parser stampe out:

$ scalac -Xprint:parser test.scala 
[[syntax trees at end of     parser]] // test.scala 
package <empty> { 
    object Test extends scala.AnyRef { 
    def <init>() = { 
     super.<init>(); 
    () 
    }; 
    List(1, 2, 3).flatMap(((x) => List(4, 5, 6).map(((y) => x.$times(y))))) 
    } 
} 

Per ottenere un elenco completo delle fasi di compilazione applicabili a -Xprint:<phase> fare questo:

$ scalac -Xshow-phases 
      phase name id description 
      ---------- -- ----------- 
       parser 1 parse source into ASTs, perform simple desugaring 
        namer 2 resolve names, attach symbols to named trees 
     packageobjects 3 load package objects 
        typer 4 the meat and potatoes: type the trees 
       patmat 5 translate match expressions 
     superaccessors 6 add super accessors in traits and nested classes 
      extmethods 7 add extension methods for inline classes 
       pickler 8 serialize symbol tables 
       refchecks 9 reference/override checking, translate nested objects 
      selectiveanf 10 
      selectivecps 11 
       uncurry 12 uncurry, translate function values to anonymous classes 
       tailcalls 13 replace tail calls by jumps 
      specialize 14 @specialized-driven class and method specialization 
      explicitouter 15 this refs to outer pointers, translate patterns 
       erasure 16 erase types, add interfaces for traits 
      posterasure 17 clean up erased inline classes 
       lazyvals 18 allocate bitmaps, translate lazy vals into lazified defs 
      lambdalift 19 move nested functions to top level 
      constructors 20 move field definitions into constructors 
       flatten 21 eliminate inner classes 
        mixin 22 mixin composition 
       cleanup 23 platform-specific cleanups, generate reflective calls 
        icode 24 generate portable intermediate code 
       inliner 25 optimization: do inlining 
inlineExceptionHandlers 26 optimization: inline exception handlers 
       closelim 27 optimization: eliminate uncalled closures 
        dce 28 optimization: eliminate dead code 
        jvm 29 generate JVM bytecode 
       terminal 30 The last phase in the compiler chain 

Il 01 L'opzioneè applicabile anche a scala e quindi al REPL.Tuttavia, vedrai anche tutto il codice wrapper degli inserti REPL.

$ scala -Xprint:parser 
Welcome to Scala version 2.10.3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_25). 
Type in expressions to have them evaluated. 
Type :help for more information. 

<..a lot of initialisation code printed..> 

scala> object Test { 
    | for(x <- List(1,2,3); y <- List(4,5,6)) yield x*y 
    | } 
[[syntax trees at end of     parser]] // <console> 
package $line3 { 
    object $read extends scala.AnyRef { 
    def <init>() = { 
     super.<init>(); 
    () 
    }; 
    object $iw extends scala.AnyRef { 
     def <init>() = { 
     super.<init>(); 
     () 
     }; 
     object $iw extends scala.AnyRef { 
     def <init>() = { 
      super.<init>(); 
     () 
     }; 
     object Test extends scala.AnyRef { 
      def <init>() = { 
      super.<init>(); 
      () 
      }; 
      List(1, 2, 3).flatMap(((x) => List(4, 5, 6).map(((y) => x.$times(y))))) 
     } 
     } 
    } 
    } 
} 

[[syntax trees at end of     parser]] // <console> 
package $line3 { 
    object $eval extends scala.AnyRef { 
    def <init>() = { 
     super.<init>(); 
    () 
    }; 
    lazy val $result = $line3.$read.$iw.$iw.Test; 
    val $print: String = { 
     $read.$iw.$iw; 
     "".$plus("defined module ").$plus("Test").$plus("\n") 
    } 
    } 
} 

defined module Test 

scala> 
17

Che ne dici di una macro?

import scala.reflect.macros.Context 
import scala.reflect.runtime.universe._ 
import scala.language.experimental.macros 

def _desugar(c : Context)(expr : c.Expr[Any]): c.Expr[Unit] = { 
    import c.universe._ 
    println(show(expr.tree)) 
    reify {} 
} 

def desugar(expr : Any) = macro _desugar 

questo può essere utilizzato direttamente nel REPL, secondo la vostra richiesta:

scala> desugar { for(i <- List(1,2,3,4,5)) yield i } 
immutable.this.List.apply[Int](1, 2, 3, 4, 5).map[Int, Any](((i: Int) => 
i))(immutable.this.List.canBuildFrom[Int]) 

scala> desguar { for(i <- (0 to 10) if (i > 5)) yield i } 
scala.this.Predef.intWrapper(0).to(10).withFilter(((i: Int) => i.>(5))).map[Int, 
Any](((i: Int) => i))(immutable.this.IndexedSeq.canBuildFrom[Int]) 

funziona anche su altre espressioni arbitrarie.

scala> desugar { 
    | val x = 20 
    | val y = 10 
    | println(x + y) 
    | } 
{ 
    val x: Int = 20; 
    val y: Int = 10; 
    scala.this.Predef.println(x.+(y)) 
} 

Questo è probabilmente il più vicino si arriva a quello che stai chiedendo, senza mai dover compilare o scaricare i dati in un file in qualsiasi momento. È possibile definire la macro direttamente nel REPL o in un file esterno caricato con il comando :load.

2

In scala 2.11, è anche possibile utilizzare quasiquotes:

val universe: scala.reflect.runtime.universe.type = scala.reflect.runtime.universe 
import universe._ 
val tree = q""" 
    val x = 20 
    val y = 10 
    println(x + y) 
""" 
println(tree) 
2

Intellij ha una funzione denominata "Explain Scala" che fa un sacco di Dezuccheraggio compreso l'ampliamento espressioni for in carta/flatMap/filtro direttamente nel file che stai modificando.

Si prega di notare che dal momento che IntelliJ 2017.1 questo è ora chiamato "Codice Scala Desugar" ed è nel menu "Codice" (grazie Mikaël per le informazioni).

IntelliJ Desugar Scala

+0

Non funziona nel mio caso. –

+0

Dettagli per favore? – ChoppyTheLumberjack

+0

Dall'ultima versione di IntelliJ funziona di nuovo. Ma nota che non è scritto "Explain Scala", ma "Desugar Scala Code" –

Problemi correlati