维坦

感谢您的关注!


  • Aug
    30

    F# CTP 1.9.6.0 发行说明(Release Notes)摘要

    Filed under: 编程; Tagged as:

    原文链接:

    http://blogs.msdn.com/dsyme/archive/2008/08/29/detailed-release-notes-for-the-f-september-2008-ctp-release.aspx

    先说说我自己的试用体验:

    • 源代码可以排序了, 右键菜单上虽然没有显示快捷键, 但是可以通过按 ALT + Up/Down 来换位.
    • CTRL + E, C 注释的时候不再是 (* *) 了, 而是与 C# 相同的多行 //.
    • CTRL + K, F 代码格式化仍然不可用, 哭...
    • 智能感知比之前流畅了些, 但仍有待提高, 回车换行后仍然不能自动缩进.

    工具:

    项目文件

    • 项目文件扩展名改为 .fsproj 并且支持 MSBuild.

    引用文件

    • #r 引用现在只能用于 .fsx 文件
    • 在 Windows 平台上使用 #r 引用注册表 AssemblyFoldersEx 中的程序集时不必指定路径. (指在添加引用对话框中默认可见的程序集, 例如可以直接 #r "System.Xml.Linq.dll")
    • 默认情况下脚本是不包含在项目中的(不参与编译), 而且你必须另外详尽的指定所引用的程序集(项目引用不等于脚本能用).
    • #load 对智能感知也会有作用.
    • #use 被移除了.

    编译器命令行

    • --generate-interface-file 改为 --sig
    • --no-warn 改为 --nowarn
    • -O3 改为 -optimize 或 -O

    语言:

    度量单位的推导与检查

    • [<Measure>]
      type 米
      [<Measure>]
      type 秒

      let dist = 100.0<米>
      let time = 9.69<秒>
      let speed = dist / time   // val it : float<米/秒> = 10.31991744
      // let foo = dist + time   // 错误: The unit of measure '秒' does not match the unit of measure '米'

    轻量级语法

    • #light 和 #light "off" 在 .fs .fsx .fsi 文件中是必须的, 但在 .ml 和 .mli 文件中隐含为 #light "off".

    隐式转换

    • 可能之前你已经听说过 F# 放弃隐式转换的一个理由是类型推断, 但是适当的时候如果能实现自动 Upcast 也不错:
      // Class
      type Base() =
          member b.X = 1
      type Derived(i : int) =
          inherit Base()   // 顺便说句: 继承之后的 as base 已经不可用了, 默认即为 base
          member d.Y = i
      let d = new Derived(7)
      let f (b : Base) = b.X
      let res = f d

      // Record
      type Rec = { A : Base ; X : int }
      let r = { A = new Derived(7); X = 12}

      // Union
      type Uni = A of Base | X of int
      let u = A(new Derived(7))

      // Mutable field
      type Rec2 = { mutable A : Base ; X : int }
      let r2 = { A = new Derived(7); X = 12}
      r2.A <- new Derived(3)

    • 以下情况不适用:
      // tuple creation
      // list elements
      // function binding and "return types"
      // if/then/else

    改进工程实践

    • #nowarn 的范围扩大到文件末尾 (为什么不是项目末尾?)
    • open 打开命名空间必须指定完整路径
      open System
      open Windows   // 警告
      open Forms   // 警告
      open System.Windows.Forms   // 正确

    命名空间缩写

    • 模块缩写不能用于命名空间
      module WF = System.Windows.Forms   // 错误 因为 Forms 不是模块.

    assert(false)

    • assert 现在与 System.Diagnostics.Debug.Assert 相同, 在 Release 版本中忽略.

    AutoOpenAttribute

    • // 当命名空间被打开时, 模块也随之自动打开.
      namespace ViTarn
      [<AutoOpen>]
      module Utils

    支持 COM 自动和可选参数

    操作符的定义更加简单

    • type Receiver(latestMessage:string) =
          static member (<--) (receiver:Receiver,message:string) =
              Receiver(message)
          static member (-->) (message,receiver:Receiver) =
              Receiver(message)
      let r = Receiver "no message"
      r <-- "Message One"
      "Message Two" --> r

    分割操作

    • 自定义分割操作符变的更加简单
      e1.[e2opt.. e3opt]   --> e1.GetSlice(arg2,arg3)
      e1.[*]               --> e1.GetSlice(None,None)

    序列和计算表达式

    • 省略执行命令时的 do 前缀
      let s =
          seq { for i in 1..12 do
                printfn "i = %A" i
                yield i+2 }
    • let 拥有与常规相同的语法
      let s2 =
          async { let rec f x = f x + 1
                  return 1 }
    • 序列化表达式要有 seq 前缀
      seq {1; 2; 3}
    • -> 和 ->> 在除 seq 之外的地方声明反对

    内置函数也会产生代码

    改进调试

    • 增强了单步调试, 虽然这已经是 .NET 上其他编译器都具备的, 但在 F# 编译器上必须禁用 tailcalls (--optimize- notailcalls)

    库:

    反射

    • Microsoft.FSharp.Reflection 更趋向于 .NET 内置的反射.

    引用

    • 可用的命名空间:
      Microsoft.FSharp.Quotations
      Microsoft.FSharp.Quotations.Patterns
      Microsoft.FSharp.Quotations.DerivedPatterns
      Microsoft.FSharp.Quotations.ExprShape
    • Microsoft.FSharp.Quotations.Raw 和 Microsoft.FSharp.Quotations.Typed 被移除
    • Expr<_> 变成 Expr 的子类型.
    • 值的结合 "comes for free"
      let f (x:int) = <@ 3 + x @>
    • 表达式的结合使用 %expr
      let f (expr:Expr) = <@ 3 + %expr @>
    • 原本的活动匹配在这里 Microsoft.FSharp.Quotations.Patterns, 还有些帮助类在 Microsoft.FSharp.Quotations.DerivedPatterns.
    • BindingPattern 更名为 ExprShape

    事件和委托

    • IEvent 模块更名为 Event, Event.create 语法不变.
    • 创建正规的事件 new Event<args>() 或者指定委托类型 new Event<delegate,args>().
    • 触发事件 ev.Trigger(args) 或 ev.Trigger(sender,args)
    • 公开事件 ev.Publish
    • 类型 IHandlerEvent<_> 被删除.
    • 例如:
      type MyControl() =
          let tickEvent = new Event<int>()
          member self.React() =
              tickEvent.Trigger (4)
          member self.OnTick = tickEvent.Publish

    已删除的特性

    • Unicode 语法
    • IEnumerable.*
    • List.of_IEnumerable List.to_IEnumerable (取而者: List.of_seq List.to_seq)
    • Permutation 类型
    • Func.*
    • CompatArray 和 CompatMatrix 模块. (取而者: Array Array2)
    • Microsoft.FSharp.Compatibility.CompatMatrix (仅 .NET1.1)
    • Microsoft.FSharp.Compatibility.CompatMatrix (仅 .NET1.1)
    • Microsoft.FSharp.Compatibility.CompatArray (仅 .NET1.1)
    • Microsoft.FSharp.Core.Idioms
    • Microsoft.FSharp.Core.Int8
    • Microsoft.FSharp.Core.Int16
    • string 现在是函数 'a -> string. 因此 string.Format 不可用, 使用 System.String.Format 代替. 同样 string.Empty 也不可用.
    • base 变成关键字
    • truncate 的类型改为 'a -> 'a (支持所有带 Truncate 静态方法的浮点型)
    • (type ty) 改为 typeof<ty> 和 typedefof<ty>
    • 抽象类必须标记 [<AbstractClass>]
    • 声明即可以解释为函数也可以解释为样式.
      let Node(x,l1,r1) = idxToNode(m1)   // 不总是函数定义

    F# PowerPack

    • 用于收集 F# 的扩展和兼容功能, 未来计划在 codeplex 上开源.
    • 兼容于 Ocaml 或早期版本的组件
    • Math 组件, 包括 Matrix 和 Vector 类型
    • 度量单位定义组件
    • 一些不赞成使用的组件
    • LINQ
    • 如果你不想让程序依赖附属的库, 就必须修改不赞成使用的部分, 例如:
      Sys.argv --> System.Environment.GetCommandLineArgs()
      Char.code --> int
      Char.chr --> char
      Filename.* --> Use System.IO.Path methods instead
      Bytearray --> Array

    FSharp.PowerPack.Linq.dll

    • PowerPack 支持通过 LINQ 表达式引用编辑和赋值
      open Microsoft.FSharp.Linq.QuotationEvaluation
      let q = <@ 1 + 1 @>
      q.ToLinqExpression ()   // 转换为 LINQ 表达式
      q.Compile ()   // 返回类型 'unit -> int'
      q.Eval ()   // 返回 2
    • PowerPack 支持通过 LINQ 表达式查询赋值
      open Microsoft.FSharp.Linq.Query
      type Customer = { Name:string; Data: int; Cost:float; Sizes: int list }
      let c1 = { Name="Don"; Data=6; Cost=6.2; Sizes=[1;2;3;4] }
      let c2 = { Name="Peter"; Data=7; Cost=4.2; Sizes=[10;20;30;40] }
      let c3 = { Name="Freddy"; Data=8; Cost=9.2; Sizes=[11;12;13;14] }
      let c4 = { Name="Freddi"; Data=8; Cost=1.0; Sizes=[21;22;23;24] }
      let data = [c1;c2;c3;c4]
      let db = System.Linq.Queryable.AsQueryable<Customer>(data |> List.to_seq)
      // 执行查询
      <@ seq { for i in db do
                   for j in db do
                       yield (i.Name,j.Name) } @>
    1 Comment
  • Aug
    30

    Microsoft F# 2008年9月 社区预览版已发布 (CTP)

    Filed under: 编程; Tagged as:

    下载地址

    http://www.microsoft.com/downloads/details.aspx?FamilyID=61ad6924-93ad-48dc-8c67-60f7e7803d3c&displaylang=en

    清单

    版本: 1.9.6.0
    发布日期: 8/29/2008
    语言: English
    文件大小: 13.4 MB - 13.9 MB*

    概述

    F# 2008年9月 CTP 版提供了开发应用程序所需的工具和资源 (原文说[全部], 真的全部吗?).

    F# 是 .NET Framework 上的函数式编程语言. 它兼具简洁,易于表达和组合,运行时,运行库,互操作,.NET对象模型等特点.

    F# 适合许多开发任务 - 从交互式探索脚本到基于组件的大规模软件开发. CTP 版本的 F# 对探索式开发提供进一步的支持, 同时改进了与 Visual Studio 的整合, 增进基于工具的大规模软件开发

    系统需求

    介绍

    F# CTP 有两个可用的版本 MSI 和 ZIP. Windows 用户应该安装 MSI, 可以安装所有的工具, 并且与 Visual Studio 2008 整合. 非 Windows 可以保存并解压 ZIP 查看说明书 README-fsharp.html.

    No Comments
  • Aug
    25

    冲出亚马逊 - 避开 WCF 的序列化

    Filed under: 编程; Tagged as: ,

    或许这个标题会让你觉得很是不解.

    还是先说说为什么会产生这个荒唐的想法吧:

    对于 WCF 来说最应该出现的地方应该是 IIS 中, MSDN 上的例子也是以 IIS 作宿主的居多. 但是我要存放的东西并不多, 所以我并不想用 IIS, 对于静态的页面和 Silverlight 倒还好说, 用 F# 实现的异步并发袖珍静态网站服务器在响应速度方面一点也不亚于 IIS. 至于 WCF, 几经打拼终于自承载了(Self-Host) .

    一切看起来已经没问题了, 可是我又一次败给了我的完美主义... 之前因为要解决 Silverlight 的跨域访问, 曾经在官方论坛上使用了一种构造 Message 的方法成功的把 clientaccesspolicy.xml 返回给客户端了, 这让我变的不安分起来, 要是我能把任意类型的文件返回给浏览器, 那我还自己实现网站服务器做什么?

    本来应该承载在网站中的 WCF, 如今却要扮演网站的角色, 你中有我, 我中有你, 这听起来很有趣, 我曾经这样解释给我的一个朋友听: 我要养鱼, 可我不想麻烦换水, 我希望我的鱼自己会吐出清洁富含氧气的水.

    但是如何实现呢? 似乎不管是什么都逃不过序列化这一关,
    返回字符串?
    结果根结点是 String.
    返回 FileStream 或 MemoryStream?
    够狠! 根结点仍然是序列化后的结果.

    构造 Message 么?
    我有想过, 我曾经想改变 Xml 数据主根结点名为 html, 但字符串内容被转义丢失了所有符号.

    为此郁闷了好久, 但结果却让我非常意外, 以至于我都不想写什么演示代码

    微软其实早就留好了后门: Stream
    对~ 就是这么简单 你只要把各种流 Upcast 为 Stream 就 OK 了! 哭~

    感谢和羡慕官方论坛上的 rico.sauve, 能用英文做关键词来进行搜索真好, 我就是找不到中文资料又不知道英文如何表述所以才会郁闷这么久...

    详见英文版的 MSDN, VS 附带的 MSDN 缺少这篇文章.

    How to: Create a Service That Returns Arbitrary Data Using The WCF Web Programming Model
    http://msdn.microsoft.com/en-us/library/cc681221.aspx

    No Comments
  • Aug
    16

    用于 VS2008sp1 的 SL2b2 简体中文版

    Filed under: 编程; Tagged as:

    下载地址:
    http://www.microsoft.com/downloads/details.aspx?FamilyID=50a9ec01-267b-4521-b7d7-c0dba8866434&DisplayLang=zh-cn

    具休没有什么更新, 只是为了应对 VS2008 的 SP1 补丁而存在的.

    一个 SP1 补丁就很头疼, 这次新的工具包不知道安装是否顺利...

    No Comments
  • Aug
    15

    扩展方法的使用

    Filed under: 编程; Tagged as: ,

    在AutoCAD开发中, 如果想要在命令行输出结果之前插入时间, 你会怎么做?

    当然最直接的就是拼接字符串了, 又或者定义静态方法来调用

    之前有次在群里, 好多人对我的一段F#代码惊讶不已.
    下面就是把好多人雷到的Super Code:

     
    type Editor with
        member t.WriteWithTime x =
            "[" + DateTime.Now.TimeOfDay.ToString() + "] " + x + "\n"
            |> t.WriteMessage
     
    let ed = Application.DocumentManager.MdiActiveDocument.Editor
    ed.WriteWithTime("带时间的输出风格.")
     

    看到了吗? 我给Editor"增加"了一个WriteWithTime方法!
    这叫什么? 狗尾续貂? 貂尾续狗? 汗...
    它的学名叫: 扩展方法

    如果可以这样写程序会怎么样?
    "用户密码".MD5()
    DateTime.GetMyBirthday()

    之所以我给[增加]二字括上了引号, 是因为Editor其实没变, 障眼法而已, 人称语法糖, 目的是让你写代码更舒服, 可事实上和定义静态方法也没什么区别, 深入的我也说不清楚, 看看C#3.0该怎么实现这个吧:
    注意: 这是C#3.0的新特性, 因此也只能用于VS2008. 更详细的信息请参考:
    http://msdn.microsoft.com/zh-cn/library/bb383977.aspx

     
    using System;
    using Autodesk.AutoCAD.ApplicationServices;
    using Autodesk.AutoCAD.EditorInput;
    using Autodesk.AutoCAD.Runtime;
     
    namespace EditorExt
    {
        public class Class1
        {
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
     
            [CommandMethod("Test1")]
            public void Test1()
            {
                ed.WriteMessage("WriteMessage - 普通输出.");
            }
     
            [CommandMethod("Test2")]
            public void Test2()
            {
                ed.WriteWithTime("WriteWithTime - 带时间输出.");
            }
        }
     
        static class MyExtensionMethods
        {
            // 第一个参数代表要扩展的类 前面加this修饰 调用时只显示一个message参数
            public static void WriteWithTime(this Editor editor, string message)
            {
                editor.WriteMessage("[" + System.DateTime.Now.TimeOfDay.ToString() + "] " + message + "\n");
            }
        }
    }
     

    运行结果:

    命令: netload
    命令: test1
    WriteMessage - 普通输出.
    命令: test2
    [15:52:00.2029960] WriteWithTime- 带时间输出.

    命令: Okey如我所愿
    未知命令"OKEY如我所愿"。按 F1 查看帮助。

    命令: 囧...
    未知命令"囧..."。按 F1 查看帮助。

    2 Comments
  • Aug
    13

    VS2008升级到SP1安装问题

    Filed under: 编程; Tagged as:

    昨天收到的VS2008SP1中文版推出正式版的消息, 赶忙下了个.

    VS2008SP1CHSX1512981.iso

    似乎我每次安装该系列产品都不会顺利, 这次也没让我失望, 直接就给我来了个错误, 提示让我到网站上去找个预安装前的准备工具.

    我已经习惯于此, 还在群里调侃说:"微软的安装包真是越来越微软了!"

    OK 有问题就解决问题, 边下载那个清理工具, 边查看自述说明, 发现其中一条是符合我的, 我装过Silverlight 2 beta2. 于是卸载掉, 包括之前提过的一个VS补丁, 再次安装结果还是不行...

    和我过不去, 那怎么能行, 我的钻牛角尖的毛病又犯了. (有人因此说我工作一定很闲 T_T)

    卸载VS2008重装, 这次停在了另一个地方: 进度条走到升级.NET Framework 3.5 sp1的时候出了问题, 丢给我一个错误日志:

    Microsoft .NET Framework 3.5 'package': [2] Failed to fetch setup file in CBaseComponent::PreInstall()
    .......
    WapUI: [2] DepCheck indicates Microsoft .NET Framework 3.5 'package' is not installed.

    找不到.netfx3.5??? 怎么会呢? 那我就重来, 把VS2008以及一切由它带进来的牛鬼蛇神全都清出去, 其中.netfx3.5在卸载的时候还真的碰上了问题, 幸好找到了一个专用的清理工具 dotnetfx_cleanup_tool.zip, 将.netfx3.5这个大神给请了出去.

    重装VS2008的过程倒是没碰上什么问题, 只是装SP1的话问题依旧.

    我无奈的仔细翻着自述文件, 突然发现一段:

    在未安装 .NET Framework 2.0 SP2 和 .NET Framework 3.0 SP2 的 Windows Vista 计算机上安装 Visual Studio 2008 SP1 时,可能会显示要求重新启动计算机的 Windows 自动更新通知。若允许立即重新启动 Windows Update,则将导致 Visual Studio 安装程序失败。

    解决此问题的方法:

    请将重新启动推迟到 Visual Studio SP1 安装完成后再执行。

    我亲爱的微软兄弟, 你是要婉转的告诉我打开Windows Update服务么? 那可是我装系统之后习惯性关闭的第一批服务啊? 你难道这么不了解用户的使用习惯吗?

    以前曾经开玩笑的说, Win2k8桌面上已经没有"我的电脑"了, 有的只是"计算机", 也就是说装好Win2k8以后老老实实的用就行了, 千万别乱碰, 因为那已经不再是"你"的电脑了~!~

    No Comments
  • Aug
    8

    转发消息的礼节

    Filed under: 随笔; Tagged as:

    通讯的发展让人们的交流变的越来越容易, (例如QQ群).

    一些人会精心构思一些"生动有趣的" "感人肺腑的"消息以图大面积传播, 更有甚者还要在文末加上某种利益的诱惑及恶毒的诅咒. (例如转发会变太阳升会员, 或者不转发会如何霉运甚至伤及家人)

    且不论"始作俑者"当初是以何心态, 单说那些被动传播者, 举几个典型的例子:

    没有时间观念:

    • 四川地震急需血源
      且不说是真是假, 当然我希望消息真的达到了应有的目的, 如今三个月都过去了, 难道还急需么?
    • 文殊菩萨出行日
      这个更为突出, 我们是唯物主义者本就不该相信这些, 更何况从年初到现在天天出行? 噢SORRY~我忘了天上一天地上一年...
    • 寻人启示
      这个是最难以控制的, 消息的泛滥不能说是谁的过错, 问题在于发消息的人找到找不到也不可能再来个作废声明. 所以从发出来的一刻就注定会泛滥成灾.

    没有场合观念:

    • 不打招呼的插播
      对于像我这样经常以QQ群为技术讨论平台的人来说, 大家正在兴致勃勃的谈论某一重点, 突然一束光闪过, 所有人都不知道说到哪了...
    • 各类图片 或黄 或敏感
      想想有多少人是正在上班的吧, 那么显眼的图片, 着实让我们这些上班族处于尴尬境地.

    没有道德观念:

    • 不跟着转发就会被诅咒
      祸及运气 幸福 婚姻 乃至人身安全, 更有甚者连父母家人都给带上了, 素质差到令人发指.
    • 转发会有某种好处
      这是非常常见的一种类型, 会以增加一个太阳 得多少Q币 免费升级为会员为诱饵, 我只能说, 这些人不但素质有问题, 连智商都有点不及格了, 将这种消息转发出来, 简直是在侮辱别人, 以为别人都和他自己一样容易上当...

    在这一系列事件中, 我觉得真正有危害的倒不是那些编写谣言的人, 因为编写者往往是出于某些利益考虑, 所谓人不为已天诛地灭, 为利益而编造也算是无可厚非.

    但是那些传谣者呢? 你们的目的是什么? 你们有目的么? 你们有思考么? 你们有看过么?

    No Comments