自从我去年开始学习F#和OCaml以来,我已经阅读了大量的文章,这些文章坚持认为设计模式(特别是Java)是命令式语言中缺少的功能的变通方法.我发现的一篇文章提出了相当强烈的主张:
我遇到过的大多数人都读过Gang of Four的"设计模式"一书.任何自尊的程序员都会告诉你,这本书与语言无关,而且无论你使用哪种语言,这些模式都适用于软件工程.这是一个崇高的主张.不幸的是,它与事实相去甚远.
功能语言极具表现力.在函数式语言中,人们不需要设计模式,因为语言可能是如此高级,您最终会编写概念,一起消除设计模式.
函数式编程的主要特性包括作为一等值,currying,不可变值等的函数.对我来说,OO设计模式近似于任何这些特性似乎并不明显.
另外,在支持OOP的函数式语言(例如F#和OCaml)中,对我来说很明显,使用这些语言的程序员将使用与其他OOP语言相同的设计模式.事实上,现在我每天都使用F#和OCaml,我在这些语言中使用的模式与我在Java中编写时使用的模式之间没有明显的差异.
功能编程是否消除了对OOP设计模式的需求,是否有任何理由?如果是这样,您是否可以发布或链接到典型OOP设计模式及其功能等效的示例?
我理解Big-O表示法,但我不知道如何为许多函数计算它.特别是,我一直试图弄清楚Fibonacci序列的幼稚版本的计算复杂性:
int Fibonacci(int n)
{
if (n <= 1)
return n;
else
return Fibonacci(n - 1) + Fibonacci(n - 2);
}
Run Code Online (Sandbox Code Playgroud)
Fibonacci序列的计算复杂度是多少以及如何计算?
假设我有一个4核CPU,我想在最短的时间内运行一些进程.这个过程理想上是可并行化的,所以我可以在无限数量的线程上运行它的块,每个线程花费相同的时间.
由于我有4个内核,我不希望通过运行比内核更多的线程来加速,因为单个内核只能在给定时刻运行单个线程.我对硬件知之甚少,所以这只是猜测.
在比线程更多的线程上运行可并行化的进程是否有好处?换句话说,如果我使用4000个线程而不是4个线程运行它,我的进程会更快,更慢,还是在大约相同的时间内完成?
Steve Yegge 在他的博客上发表评论:
世界上所有最伟大的工程师都使用Emacs.改变世界的类型.不是你旁边的立方体中的伟大gal.不是弗雷德,大厅里那个了不起的人.我说的是我们这个行业最伟大的软件开发人员,他们改变了行业的面貌.James Goslings,Donald Knuths,Paul Grahams,Jamie Zawinskis,Eric Bensons.真正的工程师使用Emacs.你必须聪明地使用它,如果你能掌握它,它会让你变得非常强大.如果你不相信我的话,在他工作的时候去看看Paul Nordstrom的肩膀.对于那些在整个职业生涯中使用过类似Visual Blub .NET的IDE的人来说,这真是令人大开眼界.
Emacs是100年的编辑.
上一次我使用文本编辑器编写代码时,大约1000年前我还在记事本中编写HTML.从那时起,我已经或多或少地依赖于IDE,在我的整个职业生涯中使用过Visual Studio,NetBeans,IntelliJ,Borland/Codegear Studio和Eclipse.
对于它的价值,我已经试过的Emacs,我的经验是,因为它完全缺乏外的开箱发现的功能,一个令人沮丧的.(显然有一个用于发现其他Emacs命令的Emacs命令,顺便说一句我找不到它 - 就像生活在你自己残酷的禅宗般的笑话中一样.)我试着让自己像这个程序好一个月,但最终决定我宁愿拖放GUI设计器,智能感知和交互式调试.
将事实与狂热主义分开是很难的,所以我不愿意接受Yegge的评论.
在依赖IDE的人和那些不依赖IDE的人之间,技能,生产力或编程乐趣是否存在可衡量的差异,或者这只是狂热主义?
我知道.NET中的结构不支持继承,但不清楚为什么它们以这种方式受限.
什么技术原因阻止结构继承其他结构?
在几乎所有的例子中,ML类型语言中的y-combinator都是这样编写的:
let rec y f x = f (y f) x
let factorial = y (fun f -> function 0 -> 1 | n -> n * f(n - 1))
Run Code Online (Sandbox Code Playgroud)
这可以按预期工作,但使用时定义y组合器感觉就像是作弊let rec ...
.
我想使用标准定义在不使用递归的情况下定义此组合器:
Y = ?f·(?x·f (x x)) (?x·f (x x))
Run Code Online (Sandbox Code Playgroud)
直接翻译如下:
let y = fun f -> (fun x -> f (x x)) (fun x -> f (x x));;
Run Code Online (Sandbox Code Playgroud)
然而,F#抱怨它无法弄清楚类型:
let y = fun f -> (fun x -> f (x x)) (fun x -> f …
Run Code Online (Sandbox Code Playgroud) 在我编程的10年里,我可以计算我一方面使用的数据结构的数量:数组,链表(我将堆栈和队列放在一起)和字典.考虑到我编写的几乎所有应用程序都属于数据形式/ CRUD类别,这并不奇怪.
我从来不需要使用红黑树,跳过列表,双端队列,循环链表,优先级队列,堆,图或过去50年来研究过的数十种奇异数据结构中的任何一种.我觉得我错过了.
这是一个开放式的问题,但这些"异国情调"的数据结构在实践中使用在哪里?有没有人有使用这些数据结构解决特定问题的实际经验?
我正在使用SQL Server 2000,并且许多存储过程都广泛使用临时表.数据库有很多流量,我担心创建和删除临时表的线程安全性.
假设我有一个存储过程,它创建了一些临时表,它甚至可以将临时表连接到其他临时表等.还可以说两个用户同时执行存储过程.
是否有可能一个用户运行sp并创建一个名为#temp的临时表,另一个用户运行相同的sp但是因为数据库中已经存在一个名为#temp的表而被停止了?
如果同一个用户在同一个连接上执行两次相同的存储过程怎么样?
是否有任何其他奇怪的场景可能导致两个用户查询相互干扰?
假设我有一个如下定义的二叉树数据结构
type 'a tree =
| Node of 'a tree * 'a * 'a tree
| Nil
Run Code Online (Sandbox Code Playgroud)
我有一个树的实例如下:
let x =
Node
(Node (Node (Nil,35,Node (Nil,40,Nil)),48,Node (Nil,52,Node (Nil,53,Nil))),
80,Node (Node (Nil,82,Node (Nil,83,Nil)),92,Node (Nil,98,Nil)))
Run Code Online (Sandbox Code Playgroud)
我正在尝试将树打印成易于理解的东西.最好,我想在控制台窗口中打印树,如下所示:
_______ 80 _______
/ \
_ 48 _ _ 92 _
/ \ / \
35 52 82 98
\ \ /
40 53 83
Run Code Online (Sandbox Code Playgroud)
有什么方法可以让我的树以这种格式输出?
根据这篇文章,F#支持对象实例和静态类的扩展方法.例如:
module CollectionExtensions =
type System.Linq.Enumerable with
static member RangeChar(first:char, last:char) = {first .. last}
open ExtensionFSharp.CollectionExtensions
Run Code Online (Sandbox Code Playgroud)
如果我键入System.Linq.Enumerable.
,静态方法将RangeChar
出现在我的Intellisense窗口中.
我想for_alli
在Seq模块中添加一个静态方法.我已经修改了上面的代码,如下所示:
module SeqExtensions =
type Microsoft.FSharp.Collections.Seq with (* error on this line *)
static member for_alli f l =
l
|> Seq.mapi (fun i x -> i, x)
|> Seq.for_all (fun (i, x) -> f i x)
Run Code Online (Sandbox Code Playgroud)
虽然两个代码片段都具有相同的结构,但是SeqExtensions
不能编译.F#突出显示该单词Seq
并返回错误"未定义类型'Seq'".
如何在Seq模块上创建静态扩展方法?
f# ×3
.net ×1
big-o ×1
cpu ×1
emacs ×1
fibonacci ×1
inheritance ×1
oop ×1
pretty-print ×1
sql-server ×1
struct ×1
temp-tables ×1
text-editor ×1
vi ×1
y-combinator ×1